Zai*_*rja 6 performance sql-server index-tuning sql-server-2012 query-performance
我有一个包含 20 列和大约 600,000 条记录的表。最大行大小仅为 100 字节左右。该表每隔几天重新填充一次,但记录数保持大致相同。
现在只有一个聚集索引:主键的 int 标识列。
我有几个依赖于这个表的查询和视图,通常需要 5-10 秒来执行。当我简单地选择所有记录 ( select * from myTable
) 时,检索所有结果大约需要 4 秒钟。
我一直无法找到在 SQL Server 中选择 500,000 条记录的相关基准。这个时间是典型的吗?
这是我在表上执行的典型查询:
select CO.Company
,CO.Location
,CO.Account
,CO.SalesRoute
,CO.Employee
,CO.ProductType
,CO.Item
,CO.LoadJDate
,CO.CommissionRate
,SUM(CO.[Extended Sales Price]) AS Sales_Dollars
,SUM(CO.[Delivered Qty]) AS Quantity
from dbo.Commissions_Output CO
where CO.[Extended Sales Price] <> 0
group by CO.Company
,CO.Location
,CO.Account
,CO.SalesRoute
,CO.Employee
,CO.ProductType
,CO.Item
,CO.LoadJDate
,CO.CommissionRate
Run Code Online (Sandbox Code Playgroud)
当我在表上至少有一个非聚集索引时,我得到以下结果:
扫描计数 18,逻辑读取 18372;CPU 时间 = 24818 毫秒,已用时间 = 8614 毫秒。
我尝试了各种索引和组合(过滤器列上的索引,包括分组列;所有过滤器/分组列上的索引并包括聚合列;等等)。它们都提供相同的性能,并且几乎总是使用相同的执行计划。
当我删除除聚集索引 (PK) 之外的所有内容时,性能通常最多可提高 3-4 秒。当扫描计数减半时,逻辑读取减少。
关于数据的一些注意事项:分组前的select和where子句的结果大约是50万行(几乎是整个表)。通过分组只合并了大约 10,000 行,在分组后仍然留下大约 500,000 条记录。
没有非聚集索引的执行计划显示,成本最高的操作是哈希匹配 (49%) 和 where 子句的聚集索引扫描 (35%)。MSSMS 建议我为[Extended Sales Price]
. 具有至少一个非聚集索引的执行计划显示成本最高的操作是排序(在 group-by 列上)。
鉴于此查询返回几乎所有记录并且 group-by 几乎没有减少行数,这是查询可以达到的速度吗?它看起来很慢,我阅读了关于人们在 1000 毫秒内返回数十万行的文章和问题。我错过了什么,或者这是一个相当典型的速度?规范化这个表目前不是一个选项,我不确定这会有多大帮助。
最后一个注意事项:我有几个视图和其他涉及加入该表的查询(有一些规范化)。起初我认为这些视图和查询由于连接不良等原因而变慢,但看起来真正的罪魁祸首是这张表和对它的初始查询。大多数查询和视图都适用于表中的几乎所有数据。当我选择单列或一小部分行时,执行时间很好,但这种情况很少见。
更新:这里是所有的执行时间、计划和 IO 统计信息。我没有将每个查询运行数百次,但执行时间似乎没有超过 1000 毫秒的“热”与“冷”的差异。
无非聚集索引,无 MAXDOP 设置:
表'Commissions_Output'。扫描计数 9,逻辑读 11263,物理读 0,预读 0,lob 逻辑读 0,lob 物理读 0,lob 预读 0。
CPU 时间 = 6690 毫秒,已用时间 = 4605 毫秒。(最大 CPU 时间 = 7516 毫秒,最小运行时间 = 3754 毫秒。)
使用非聚集索引,无 MAXDOP 设置:
表'Commissions_Output'。扫描计数 16,逻辑读取 6227
CPU 时间 = 6591 毫秒,已用时间 = 3717 毫秒。
没有非聚集索引,MAXDOP 1
:
表'Commissions_Output'。扫描计数 1,逻辑读取 10278
CPU 时间 = 2656 毫秒,已用时间 = 4991 毫秒。
使用非聚集索引,MAXDOP 1
:
表'Commissions_Output'。扫描计数 1,逻辑读取 10278
CPU 时间 = 2656 毫秒,已用时间 = 4991 毫秒。
使用的非聚集索引:
create nonclustered index IX_NC_Comm_Output on dbo.Commissions_Output([Extended Sales Price])
include (company, location, account, salesroute, employee, producttype, item, loadjdate, commissionrate, [delivered qty])
Run Code Online (Sandbox Code Playgroud)
您测试过的非聚集索引并不是最适合此查询的索引。它可以用于WHERE
子句和执行索引扫描而不是全表扫描,但不能用于GROUP BY
.
最好的索引必须是部分索引(以过滤子句中不需要的行WHERE
),然后使用 中使用的所有列GROUP BY
,然后INCLUDE
使用 中的所有其他列SELECT
:
CREATE INDEX special_ix
ON dbo.Commissions_Output
( company, location, account,
salesroute, employee, producttype,
item, loadjdate, commissionrate )
INCLUDE
( [Extended Sales Price], [Delivered Qty] )
WHERE
( [Extended Sales Price] <> 0 ) ;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
32527 次 |
最近记录: |