数据库(〜2TB)缓慢的MSSQL – 索引/碎片?

我有一个相当大的MS SQL数据库(〜2TB)。 大部分数据都在一个表中(约60亿行)。

两个星期前,我在大表上删除了两个非聚簇索引,并将数据迁移到单个6TB RAID SSDarrays上。 然后,我重新创build了两个索引,花了相当一段时间(假设因为我目前有数据(表和索引)和login在同一个arrays,似乎与RAID我不能有快速顺序和随机读写与此同时)。

无论如何,重build索引后,它运行了大约一个星期。 在这个星期里,我一直在大桌子上慢慢地清理干净,这只是删除不需要的旧行。 到目前为止,我已经从60亿中删除了大约3亿,估计还有很多事情要做。

现在运行了大约一周后,现在运行速度非常慢,我不确定哪个是最好的。

现在的情况:

  • 双至强
  • 192GB内存
  • 带有SQL Server 2012的Windows Server 2012
  • CPU达到100%(16核心) – 在放缓之前只使用了大约50%
  • IO似乎不太努力(没有队列)

大表目前有(我现在没有任何碎片信息):

  • 1x聚集指数:48%碎片
  • 1x非聚簇索引:36%分段
  • 1x非聚簇索引:10%碎片
  • 我曾经在这个桌子上有两个索引,但不久前就放弃了

你认为最好的解决我的问题

  • 在同一个数组上重build非聚集索引(假设这样可以解决这个问题,但是需要很长时间才能完成,在不久的将来可能会出现同样的问题,因为我还在清理这个表)
  • 在新的RAIDarrays上重build非聚簇索引(应该像上面那样修复,但可能会更快)
  • 将非聚簇索引移动到新的RAIDarrays(最快的选项)
  • 在新的RAIDarrays上重新创build两个旧索引(不确定是否可以减轻CPU或IO压力)

碎片索引是否会导致更高的CPU使用率?

还有什么我可以失踪?

TIA

基于你在索引上的碎片量,你应该继续并重build它们。 任何碎片大于30%的索引都应该被重build。 我也会确保你定期更新表格上的统计数据(重build索引会自动完成)。

这样做后,如果你仍然看到真正的高CPU,你已经确认这是SQLServr.exe进程,那么你会想要缩小哪些查询使用这么多的CPU,并从那里排除故障。

你可以运行类似于下面的查询来获得关于已经使用最多CPU的查询的一些聚合数据:

SELECT TOP 5 total_worker_time/execution_count AS [Avg CPU Time], total_logical_writes as [Total Writes], total_logical_reads as [Total Reads], SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS statement_text FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ORDER BY total_worker_time/execution_count DESC; 

对于实时数据,你也可以运行这样的东西:

 SELECT er.session_id, er.cpu_time, er.reads, er.writes, SUBSTRING(st.text, (er.statement_start_offset/2)+1, ((CASE er.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE er.statement_end_offset END - er.statement_start_offset)/2) + 1) AS statement_text FROM sys.dm_exec_requests AS er CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) as st WHERE session_id > 50 AND status = 'runnable' ORDER BY cpu_time desc 

您也可以同时运行以比较实时数据和汇总数据。 两者都应该给你一个关于什么是使用这么多CPU的想法。 从那里你会想知道为什么他们跑这么长时间。 他们正在做大量的读或一吨写? 如果他们做了大量的读取,可能意味着他们缺less一些索引。 大量的写入可能意味着索引实际上是问题。

无论哪种方式关注这些陈述可以给你一个出发点。