Sup*_*oss 4 sql-server indexing join
如果我有以下查询:
select some cols
from tbl_a
INNER JOIN tbl_b ON tbl_a.orderNumber = tbl_b.orderNumber
where tlb_b.status = 'XX'
Run Code Online (Sandbox Code Playgroud)
假设两个表只有订单号上的聚簇索引,从性能角度来看,扩展表b上的聚簇索引以包括where子句中引用的状态列会更好吗?
你扩展tbl_b以在orderNumber 之后添加状态:create clustered index ... on tbl_b(orderNumber, status).对于上面的查询,没有明显的区别.该计划仍然必须端到端扫描tbl_b并匹配tbl_a中的每个订单号(可能是合并连接).
您可以扩展tbl_b以在orderNumber 之前添加状态:create clustered index ... on tbl_b (status, orderNumber).现在有一个巨大的差异.该计划可以在tbl_b上进行范围扫描,仅使用状态'xx'进行范围扫描,并且仅使用嵌套循环连接匹配对应orderNumber的tbl_a.
放置一个低选择性列(通常是'status')作为索引中最左边的键通常是一件好事.在"聚集索引"中最左边的列创建"状态"行通常也是一件好事,因为它将具有相同状态的记录物理地组合在一起.请注意,这样做会对所有查询产生影响.如果没有指定status,你也会通过orderNumber松开直接访问,你必须单独在orderNumber上添加一个非聚集索引来覆盖它(通常是PK非聚集索引).
我知道你的实际数据基数和选择性,我做了所有这些评论.如果tbl_a和tbl_b的基数非常偏差,那么事情可能会有所不同.例如.如果tbl_a有10个记录,其中包含10个不同的订单号,而tbl_b有10M记录,其中10M订单号超过我的建议,则选项2将没什么区别,因为该计划将始终选择tbl_a扫描tbl_b中的搜索范围查找10次.