【发布时间】:2020-10-23 23:17:37
【问题描述】:
我正在努力确定有效的索引(或重写查询)以改进具有以下混淆谓词的查询:
- 在一个范围内的一个表的日期上加入 - 在第二个表的两个日期字段之间(一个可以为空,一个在 PK 中不能为空)。
- 使用的日期实际上是日期字段中的值(可为空)+1。
- WHERE 子句在多个标志字段上包含 OR 逻辑。
查询的简化版本是:
select
d.dim_date_id
,f.dim_provider_id
,f.dim_event_id
,d.date
from DWH.dbo.tbl_fact_outcome f
join DWH.dbo.tbl_dim_date d on DATEADD(DAY,1,d.date) between f.known_from and f.known_to
where
f.known_from > getdate()-12
and (d.flag_latest_day = 'Y' or d.flag_end_of_month = 'Y' or (d.flag_end_of_week = 'Y' AND d.flag_latest_week = 'Y'))
and d.flag_future_day = 'N'
and f.deleted = 0
tbl_fact_outcome 有这些索引:
- input_form_id 上的 PK 聚簇索引,known_from
- deleted、known_from、known_to 上的非唯一非聚集索引(包括所需的 _dim_id 字段)
tbl_dim_date 有这些索引:
- dim_date_id 上的 PK 聚簇索引
- flag_future_day 上的非唯一非聚集索引,日期(包括相关标志字段)
目前,它估计有 853 行,但返回 16,784。
这是查询计划: https://www.brentozar.com/pastetheplan/?id=rydKb_3AI
统计数据是最新的。 我尝试重新排序覆盖索引,但没有任何改进。
我完全不知道还有什么可以尝试使用索引或代码本身来提高性能,所以任何指针都值得赞赏。
编辑 05/07/2020
这里排除了以下建议:
- tbl_fact_outcome 上的过滤索引(删除时) - 不到 1% 的记录将被过滤掉,因此不值得
- tbl_dim_date 上的过滤索引(使用查询中的整个 WHERE 子句) - 无法在索引中使用 OR
- tbl_dim_date 上的索引,包含字段作为关键字段 - 尝试过这个,没有任何区别,优化器没有使用。
【问题讨论】:
-
您的索引是否有过滤条件或者它们是未过滤的索引?
-
它们是未过滤的
-
d.flag_future_day是什么意思?我对此有不好的预感。
-
SMor - 该表是日期列表,字段 flag_future_day 是一个 Y/N 标志,用于标识未来的日期。
标签: sql-server optimization indexing query-tuning