Sei*_*bar 16 sql-server optimization
我有两个类似的查询,它们生成相同的查询计划,只是一个查询计划执行了 1316 次聚集索引扫描,而另一个执行了 1 次。
两个查询之间的唯一区别是不同的日期标准。长时间运行的查询实际上更窄了日期条件,并拉回了更少的数据。
我已经确定了一些对这两个查询都有帮助的索引,但我只想了解为什么 Clustered Index Scan 操作符在一个查询上执行 1316 次,而这个查询实际上与它执行 1 次的查询相同。
我查看了正在扫描的PK的统计数据,它们是相对最新的。
原始查询:
select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
select incident_id as exported_incident_id
from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-06-01 00:00:00.000' and '2011-07-01 00:00:00.000'
and exported_incidents.exported_incident_id is not null
Run Code Online (Sandbox Code Playgroud)
生成这个计划:
缩小日期范围标准后:
select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
select incident_id as exported_incident_id
from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'
and exported_incidents.exported_incident_id is not null
Run Code Online (Sandbox Code Playgroud)
生成这个计划:
扫描后的 JOIN 提供了一个线索:最后一个连接的一侧有较少的行(当然从右到左阅读)优化器选择“嵌套循环”而不是“哈希连接”。
但是,在查看这个之前,我的目标是消除 Key Lookup 和 DISTINCT。
关键查找:您在 FIR_Incident 上的索引应该覆盖,可能(FI_IncidentDate, incidentid)
或相反。或者两者都有,看看哪个更常用(它们都可能是)
该DISTINCT
是的结果LEFT JOIN ... IS NOT NULL
。优化器已经删除了它(计划在最后的 JOIN 上有“左半连接”),但为了清晰起见,我会使用 EXISTS
就像是:
select
F.IncidentID
from
FIR_Incident F
where
exists (SELECT * FROM postnfirssummary P
WHERE P.incident_id = F.incidentid)
AND
F.FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'
Run Code Online (Sandbox Code Playgroud)
您还可以使用计划指南和 JOIN 提示使 SQL Server 使用散列连接,但首先尝试使其正常工作:指南或提示可能经不起时间的考验,因为它们仅对数据和您现在运行的查询,而不是将来运行
归档时间: |
|
查看次数: |
5216 次 |
最近记录: |