Kev*_*3NF 3 performance sql-server sql-server-2014 query-performance
如果答案是“不”,我可以接受...
我想看看这是否可以优化......它是更大的存储过程的一部分。CGCode
是 varchar(50),Year
并且Month
是smallint
,FEIN
是char(9)
select max(id)
from Table
where 1=1
and cgcode = 123
and datefromparts(cast(year as char(4)),cast(month as char(2)),'01') < getdate()
and totalcount > 0
group by cgcode, year, month, fein
Run Code Online (Sandbox Code Playgroud)
实际执行计划的逻辑读取:1,566,473
源表原始数据 3200万+条记录
估计行数:640K,实际 55K,在 Group By 开始之前
上的隐式转换警告Year/Month/CGCode
(作为bigint
)
执行时间大约为 7.5 秒,执行非聚集索引查找:
最终结果集是 114 行(为此,CGCode
我们测试...其他各不相同)
Prod 的性能在比 Dev box 明显更好的硬件上大致相同。随着时间的推移,这只会变得更糟,因为它会提取比当前月份更旧的所有内容,以在 UI 中填充历史图表。
我还能提供哪些其他信息?
当前使用的索引:
CREATE NONCLUSTERED INDEX [COIX_Table_TotalCount] ON [dbo].[Table]
(
[TotalCount] ASC
)
INCLUDE ( [ID],
[CGCode],
[Year],
[Month],
[FEIN])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,
ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
CGCode
限制数据最多...281 个值。 year
只有 3-4 年的数据,month
当然只有 12 个选项。 TotalCount
是bigint
3200 万条记录中的 17K 个不同值。不知道TotalCount
列的目的是什么。
首先,我会重写这个条件。事实上,它不能有效地使用任何索引。:
datefromparts(cast(year as char(4)),cast(month as char(2)),'01') < getdate()
Run Code Online (Sandbox Code Playgroud)
重写它,以便没有应用于列的函数或计算:
( year < year(getdate())
or year = year(getdate()) and month <= month(getdate())
)
Run Code Online (Sandbox Code Playgroud)
考虑到零件,重写将允许使用索引(cgcode, year, month)
- 或者甚至更好的索引。(cgcode, year, month, fein)
GROUP BY
接下来,如果totalcount
始终是WHERE
子句的一部分或totalcount > 0
始终使用特定条件,则可以通过将其添加到INCLUDE
部分或使用更有针对性的过滤索引来提高效率:
-- option A
index (cgcode, year, month, fein, id)
include (totalcount)
-- option B
index (cgcode, year, month, fein, id)
where (totalcount > 0)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
158 次 |
最近记录: |