我发现我们的系统在标称负载下遇到了节流墙,例如每个实例每秒 120 次插入。还有其他并发进程正在运行,我们正在卸载/优化等。我想知道的是:是否有人对索引的存在对节流的影响程度有任何见解?我在系统的其他地方有一些性能问题,索引的存在会有所帮助,但我犹豫要不要添加它们,因为它们有额外的 CPU 和 I/O 负载!
欢迎任何现实世界的建议。请保持它特定于 SQL Azure。
我发现我们的系统在标称负载下遇到了节流墙,例如每个实例每秒 120 次插入。还有其他并发进程正在运行,我们正在卸载/优化等。我想知道的是:是否有人对索引的存在对节流的影响程度有任何见解?我在系统的其他地方有一些性能问题,索引的存在会有所帮助,但我犹豫要不要添加它们,因为它们有额外的 CPU 和 I/O 负载!
欢迎任何现实世界的建议。请保持它特定于 SQL Azure。
节流基本上只是对 CPU、内存和磁盘使用的限制。因此,索引对限制的影响归结为它对这些资源的影响。所以实际上这就像任何其他性能调整方案一样 - 找出你正在达到的限制,并确定如何减少使用它。
SQL Azure 与 SQL Server 不同,主要是因为您无法访问所有很酷的 DMV。你仍然得到一些,但不是全部。您确实获得的一个优势是,如果您遇到限制错误,它们应该告诉您您正在限制什么资源。
根据您的情况,以下查询可能会有所帮助。我从Glenn Berry那里偷了这些,我唯一的贡献是弄清楚它们在 Azure 上运行。尽管他专注于非 Azure 安装,但他也对 SQL 性能工作提出了很多很好的建议。
--List query plans and stats ordered by last execution time
SELECT TOP(50) q.text, s.last_execution_time, s.execution_count, s.total_worker_time,
s.max_elapsed_time, s.max_worker_time, (s.total_worker_time / s.execution_count) AS AverageExecutionTime,
s.max_physical_reads, s.max_logical_reads,
s.max_logical_writes, s.min_rows, s.max_rows
FROM sys.dm_exec_query_stats as s
cross apply sys.dm_exec_sql_text(plan_handle) AS q
ORDER BY s.last_execution_time DESC
--List query plans and stats ordered by average execution time
SELECT TOP(50) q.text, s.last_execution_time, s.execution_count, s.total_worker_time,
s.max_elapsed_time, s.max_worker_time, (s.total_worker_time / s.execution_count) AS AverageExecutionTime,
s.max_physical_reads, s.max_logical_reads,
s.max_logical_writes, s.min_rows, s.max_rows
FROM sys.dm_exec_query_stats as s
cross apply sys.dm_exec_sql_text(plan_handle) AS q
ORDER BY [AverageExecutionTime] DESC
--Get 50 most I/O intensive queries
SELECT TOP(50) OBJECT_NAME(qt.objectid) AS [SP Name],
qs.total_logical_writes,
qs.total_logical_reads,
(qs.total_logical_reads + qs.total_logical_writes) /qs.execution_count AS [Avg IO],
SUBSTRING(qt.[text],qs.statement_start_offset/2,
(CASE
WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(nvarchar(max), qt.[text])) * 2
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2) AS [Query Text],
qs.execution_count,
qs.creation_time
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
WHERE qt.[dbid] = DB_ID()
ORDER BY [Avg IO] DESC OPTION (RECOMPILE);
--Get executing requests
SELECT session_id, blocking_session_id, wait_type, last_wait_type, wait_time, total_elapsed_time, cpu_time, logical_reads, reads, writes
FROM sys.dm_exec_requests AS r
ORDER BY wait_time DESC
当涉及到索引时,您当然需要评估开销与查询性能改进之间的权衡。最会伤害您的是未使用的索引,因为维护索引的开销属于受到限制的类别。
如果你添加一个索引,你能摆脱另一个现在已经过时的索引吗?由于添加索引,您的查询是否消耗更少的受限资源(I/O、内存、CPU)?
另请注意,CPU 不再受到严格限制(如 I/O 或内存);查询将执行较慢,但它们会执行。
最后,我很少看到索引是限制的重要原因,除非可能是在创建索引(或刷新)时。然而,常识在 SQL Azure 中适用,就像在 SQL Server 中一样:创建不太宽的索引,并确保索引减少现有查询资源消耗。
使用 DMV 可以帮助您确定整体资源消耗是否正在下降。
确保不要对具有聚集索引的 PK 使用 GUID。