为什么此 SQL 会导致索引扫描而不是索引查找?
有人可以帮我调整这个 SQL 查询吗?
SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children,
a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID,
a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation,
a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy
FROM dbo.NPapplicants AS a INNER JOIN
dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID
WHERE (apt.Offline = 0)
AND (apt.MA = 'M')
。
执行计划如下所示:
。
我不明白的是为什么我要对 NP 申请人进行索引扫描。我有一个涵盖 BuildingID 和 ApartmentID 的索引。不应该用这个吗?
Can someone please help me tune this SQL query?
SELECT a.BuildingID, a.ApplicantID, a.ACH, a.Address, a.Age, a.AgentID, a.AmenityFee, a.ApartmentID, a.Applied, a.AptStatus, a.BikeLocation, a.BikeRent, a.Children,
a.CurrentResidence, a.Email, a.Employer, a.FamilyStatus, a.HCMembers, a.HCPayment, a.Income, a.Industry, a.Name, a.OccupancyTimeframe, a.OnSiteID,
a.Other, a.ParkingFee, a.Pets, a.PetFee, a.Phone, a.Source, a.StorageLocation, a.StorageRent, a.TenantSigned, a.WasherDryer, a.WasherRent, a.WorkLocation,
a.WorkPhone, a.CreationDate, a.CreatedBy, a.LastUpdated, a.UpdatedBy
FROM dbo.NPapplicants AS a INNER JOIN
dbo.NPapartments AS apt ON a.BuildingID = apt.BuildingID AND a.ApartmentID = apt.ApartmentID
WHERE (apt.Offline = 0)
AND (apt.MA = 'M')
.
Here's what the Execution Plan looks like:
.
What I don't understand is why I'm getting a Index Scan for NPapplicants. I have an Index that covers BuildingID and ApartmentID. Shouldn't that be used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为预计比赛将返回近 10K 条记录。使用 10K 键返回到数据以检索其他列相当于仅扫描 100K 记录(至少)并使用哈希匹配进行过滤的性能。
至于对另一个表的访问,查询优化器已确定您的索引有用(可能针对
Offline
或MA
),因此它正在寻找该索引以获取连接键。然后将这两者进行 HASH 匹配以产生最终输出。
It is because it is expecting close to 10K records to return from the matches. To go back to the data to retrieve other columns using 10K keys is equivalent to something like the performance of just scanning 100K records (at the very least) and filtering using hash match.
As for access to the other table, the Query Optimizer has decided that your index is useful (probably against
Offline
orMA
) so it is seeking on that index to get the join keys.These two are then HASH matched for intersections to produce the final output.
B-Tree
索引中的查找成本是表扫描(每条记录)的几倍。此外,应在聚集索引中进行另一次查找以检索其他列的值。
如果预计大部分记录都匹配,那么扫描聚集索引会更便宜。
为了确保优化器选择了最佳方法,您可以运行以下命令:
将
index_name
替换为索引的实际名称,并比较执行时间和I/O
数量代码>操作(如消息选项卡中所示)A seek in a
B-Tree
index is several times as expensive as a table scan (per record).Additionally, another seek in the clustered index should be made to retrieve the values of other columns.
If a large portion of records is expected to match, then it is cheaper to scan the clustered index.
To make sure that the optimizer had chosen the best method, you may run this:
Replace
index_name
with the actual name of your index and compare the execution times and the numbers ofI/O
operations (as seen in the messages tab)