sql - 查询不使用多对多关系上的索引
问题描述
我有以下查询:
select V.VisitID
from Visit V
inner join VisitDrug VD on V.VisitID = VD.VisitID
inner join Lookup.Drug D on VD.DrugID = D.DrugID
where V.StartDate >='2019-03-27 13:00:00.0000000 +00:00'
and V.StartDate <='2020-03-31 12:59:59.9990000 +00:00'
我不明白的是,每当在 VisitDrug 上进行连接操作时,它必须对表中的所有行进行全扫描,而不仅仅是那些适用的 VisitID。
目前的指标是:
ALTER TABLE [dbo].[VisitDrug] ADD CONSTRAINT [PK_VisitDrug] PRIMARY KEY CLUSTERED
(
[VisitID] ASC,
[DrugID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IDX_VisitDrug_DrugID_VisitID] ON [dbo].[VisitDrug]
(
[DrugID] ASC,
[VisitID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
执行计划是 - https://www.brentozar.com/pastetheplan/?id=Hy6QLqT8I
通过阅读其他问题,我相信索引是正确的,但没有被使用。
解决方案
因为这个查询需要大量的访问,优化器决定在 Visit.StartDate 上读取索引上的日期范围会更便宜,然后对结果进行排序,然后使用 VisitDrug 进行 MERGE JOIN。另一种方法是在 PK_VisitDrug 上执行 49,914 次单独的索引查找,总共 150,000-200,000 个逻辑 IO。
您可以通过指定LOOP JOIN来测试另一个计划。
推荐阅读
- function - 闭包是避免全局变量的方法吗?
- sql-server-2014 - 存储过程、函数和表类型在 SQL Server 2014 中不可见
- react-native - 如何在 react-native 中运行一段时间的函数?
- c# - WPF 固定宽度文本框字体(如十六进制编辑器)
- android - 如何禁用列表视图的滚动视图并为包含列表视图和其他文本视图的整个活动应用滚动视图?
- excel - 从一个工作簿复制公式,粘贴为活动工作簿中的值
- hive - sqoop hive 导入“尚未清理”异常
- javascript - 使用 for 循环索引填充请求承诺 uri
- python - Python - 如何在 QWebEnginePage 中使用 mainframe() 方法 [mainframe() 错误]
- c# - Windows 10 中的 PrintQueue Addjob 挂起问题