bde*_*ere 1 optimization sql-server-2017
我编写了一个程序来测试对单个数据库表的并发读取。我预计未来会有大量读取(无删除、插入或更新)流量,使用即席查询,这就是我预先测试以模拟这一点的原因。根据下面的日志,您可以看到随着并发读取数量的增加,完成请求所需的时间也会增加。从单个请求的 3 秒到 20 个并发请求的最长 15 秒。
我认为我不是不合理,当我向数据库发送垃圾邮件请求时,我预计它需要更长的时间来处理,但不是这么大的因素。尤其是因为服务器不受 CPU 限制,正如 SQL Server 性能仪表板在 20 个并发请求期间 CPU 使用率为 40% 所证明的那样。
Started 1.
Ended 1. Elapsed milliseconds: 2938
Started 2.
Started 4.
Started 5.
Started 3.
Started 1.
Ended 1. Elapsed milliseconds: 3204
Ended 3. Elapsed milliseconds: 4486
Ended 5. Elapsed milliseconds: 5185
Ended 2. Elapsed milliseconds: 5261
Ended 4. Elapsed milliseconds: 6075
Started 1.
Started 5.
Started 7.
Started 3.
Started 6.
Started 4.
Started 8.
Started 9.
Started 2.
Started 10.
Ended 6. Elapsed milliseconds: 4789
Ended 4. Elapsed milliseconds: 5327
Ended 3. Elapsed milliseconds: 5684
Ended 7. Elapsed milliseconds: 5732
Ended 1. Elapsed milliseconds: 6846
Ended 5. Elapsed milliseconds: 7238
Ended 8. Elapsed milliseconds: 7355
Ended 2. Elapsed milliseconds: 7551
Ended 10. Elapsed milliseconds: 7581
Ended 9. Elapsed milliseconds: 7675
Started 1.
Started 11.
Started 6.
Started 7.
Started 17.
Started 2.
Started 3.
Started 16.
Started 9.
Started 18.
Started 10.
Started 19.
Started 8.
Started 20.
Started 4.
Started 12.
Started 14.
Started 13.
Started 15.
Started 5.
Ended 8. Elapsed milliseconds: 4167
Ended 4. Elapsed milliseconds: 7327
Ended 18. Elapsed milliseconds: 9435
Ended 11. Elapsed milliseconds: 9450
Ended 10. Elapsed milliseconds: 9506
Ended 1. Elapsed milliseconds: 9884
Ended 17. Elapsed milliseconds: 9904
Ended 3. Elapsed milliseconds: 10181
Ended 19. Elapsed milliseconds: 10273
Ended 7. Elapsed milliseconds: 10640
Ended 14. Elapsed milliseconds: 11451
Ended 12. Elapsed milliseconds: 11713
Ended 15. Elapsed milliseconds: 12148
Ended 2. Elapsed milliseconds: 12304
Ended 9. Elapsed milliseconds: 12496
Ended 6. Elapsed milliseconds: 12656
Ended 16. Elapsed milliseconds: 12973
Ended 20. Elapsed milliseconds: 14306
Ended 13. Elapsed milliseconds: 14603
Ended 5. Elapsed milliseconds: 15106
Run Code Online (Sandbox Code Playgroud)
有趣的是,我发现使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED和省略它之间几乎没有区别。平均响应时间具有可比性。这是正常的吗?如果有帮助,在 SQL Server Profiler 中查看单个请求如下所示。您会注意到 CPU 和 Reads 非常高(我故意写了一个相当繁重的查询)。我还发现针对不同表的 20 个并发请求不会受到太多延迟的影响。因此,如果没有其他方法可以提高性能,我愿意拆分表格。
Audit Login -- network protocol: TCP/IP
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read uncommitted
ApplicationName LoginName 15544 (ClientProcessID) 93 (SPID) 2020-10-29 10:38:35.313
SQL:BatchStarting QueryText ApplicationName LoginName 15544 (ClientProcessID) 93 (SPID) 2020-10-29 10:38:35.320
SQL:BatchCompleted QueryText ApplicationName LoginName 2187 (CPU) 436673 (Reads) 0 (Writes) 6811 (Duration) 15544 (ClientProcessID) 93 (SPID) 2020-10-29 10:38:35.320 2020-10-29 10:38:42.130
Run Code Online (Sandbox Code Playgroud)
SQL Server 或发送给它的查询是否可以针对并发读取进行优化?如果是这样,如何?如果没有,我应该转向什么产品?
编辑:添加了附加信息。
在执行并运行 20 个并发请求后执行在sqlskills.com 上找到的脚本时DBCC SQLPERF (N'sys.dm_os_wait_stats', CLEAR)。
WaitType Wait_S Resource_S Signal_S WaitCount Percentage AvgWait_S AvgRes_S AvgSig_S Help/Info URL
SOS_SCHEDULER_YIELD 179.18 0.01 179.17 11860 95.25 0.0151 0.0000 0.0151 https://www.sqlskills.com/help/waits/SOS_SCHEDULER_YIELD
RESOURCE_SEMAPHORE 6.93 6.92 0.00 1 3.68 6.9270 6.9240 0.0030 https://www.sqlskills.com/help/waits/RESOURCE_SEMAPHORE
ASYNC_NETWORK_IO 1.57 1.56 0.01 26 0.84 0.0605 0.0600 0.0005 https://www.sqlskills.com/help/waits/ASYNC_NETWORK_IO
LCK_M_SCH_M 0.18 0.15 0.03 14 0.09 0.0127 0.0109 0.0019 https://www.sqlskills.com/help/waits/LCK_M_SCH_M
PREEMPTIVE_OS_CRYPTOPS 0.06 0.06 0.00 9 0.03 0.0067 0.0067 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_CRYPTOPS
RESERVED_MEMORY_ALLOCATION_EXT 0.05 0.05 0.00 41234 0.03 0.0000 0.0000 0.0000 https://www.sqlskills.com/help/waits/RESERVED_MEMORY_ALLOCATION_EXT
PREEMPTIVE_OS_AUTHENTICATIONOPS 0.04 0.04 0.00 9 0.02 0.0046 0.0046 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_AUTHENTICATIONOPS
PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICY 0.02 0.02 0.00 3 0.01 0.0070 0.0070 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICY
PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICYFREE 0.02 0.02 0.00 3 0.01 0.0067 0.0067 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_NETVALIDATEPASSWORDPOLICYFREE
PREEMPTIVE_OS_AUTHORIZATIONOPS 0.02 0.02 0.00 3 0.01 0.0067 0.0067 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_AUTHORIZATIONOPS
PREEMPTIVE_OS_CRYPTACQUIRECONTEXT 0.02 0.02 0.00 3 0.01 0.0067 0.0067 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_CRYPTACQUIRECONTEXT
PREEMPTIVE_OS_QUERYREGISTRY 0.02 0.02 0.00 17 0.01 0.0009 0.0009 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_QUERYREGISTRY
PAGEIOLATCH_SH 0.01 0.01 0.00 12 0.00 0.0006 0.0006 0.0000 https://www.sqlskills.com/help/waits/PAGEIOLATCH_SH
LATCH_EX 0.00 0.00 0.00 3 0.00 0.0010 0.0003 0.0007 https://www.sqlskills.com/help/waits/LATCH_EX
PREEMPTIVE_XE_CALLBACKEXECUTE 0.00 0.00 0.00 48 0.00 0.0000 0.0000 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_XE_CALLBACKEXECUTE
PREEMPTIVE_OS_CLOSEHANDLE 0.00 0.00 0.00 2 0.00 0.0000 0.0000 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_CLOSEHANDLE
PREEMPTIVE_OS_WRITEFILE 0.00 0.00 0.00 1 0.00 0.0000 0.0000 0.0000 https://www.sqlskills.com/help/waits/PREEMPTIVE_OS_WRITEFILE
Run Code Online (Sandbox Code Playgroud)
输出SELECT @@VERSION;为 Microsoft SQL Server 2017 (RTM-CU15-GDR) (KB4505225) - 14.0.3192.2 (X64) Jun 15 2019 00:45:05 Copyright (C) 2017 Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 标准 10.0(内部版本 14393:)(管理程序)。
查询消耗 2000 毫秒的 CPU 时间。因此,您的吞吐量受到 CPU 内核的限制。4 核的吞吐量是每秒 2 个查询。如果您有 30 个并发请求,它们将需要 15 秒才能完成。并且 SQL Server 的调度程序非常“公平”,因此每个查询将花费大约 15 秒,因为 SQL Server 任务每隔几毫秒就会在并发请求之间切换。
等待统计数据确认工作负载受 CPU 限制。SOS_SCHEDULER_YIELD 是当任务让出 CPU 内核并等待另一轮时的等待时间。
查询的 CPU 时间包括:
此查询需要 436,673 次读取,因此减少读取次数可能是优化的主要途径。可以使用更好的索引、更好的查询或列存储压缩来减少查询所需的读取次数。
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |