【问题标题】:Optimization using indexes on joins in SQL在 SQL 中使用连接上的索引进行优化
【发布时间】:2020-12-28 20:16:43
【问题描述】:

这可能看起来很基本,但我花了最后一个小时搜索并找不到直接答案。

让我们有两个表:tblCustomertblStore

tblCustomer 的主唯一索引为 CustomerNumberVersion

问题1:如果tblStore没有CustomerNumber作为其主键,我是否还能通过a得到更好的优化:

From 
    tblStore s 
Left Join 
    tblCustomer c On s.CustomerNumber = c.CustomerNumber

还是让“on”成为两个表的索引更好?

问题 2:我只想要客户版本为 1 的行。我应该说:

From 
    tblStore s 
Left Join 
    tblCustomer c On s.CustomerNumber = c.CustomerNumber 
                  And c.Version = 1

我认为这比稍后在 Where 子句中执行更好,但它是否使通过索引连接更好,或者 CustomerNumber 本身就足够了。

我正在查询包含很多行的内容,因此任何建议都会有所帮助。

谢谢!

【问题讨论】:

  • 如果您担心连接性能,请使用简单的递增整数主键。将条件放入 joinwhere 子句中对性能没有影响,但它会产生不同的结果。
  • 根据我的阅读,如果我在 Where 子句中放置一个条件,它最初会拉回所有行,然后在到达 Where 子句时限制它们。这不是真的吗?
  • 这根本不是真的。谓词下推意味着 SQL Server 甚至可以在加载磁盘行时直接在存储引擎上过滤它们。

标签: sql join indexing


【解决方案1】:
  1. 优化器可能会考虑是否重新排列为右连接,是否进行合并、散列或循环连接,其中第一种通常最适合大量已排序的行,第二种适合大量未排序的行行,第三个通常最适合少量行。
    我假设这个查询将选择所有商店并加入所有客户。通常你会想要一个合并连接,所以理想情况下你会索引CustomerNumber 上的两个表。这不一定是主键,它可以是辅助(非聚集)索引;主键也不一定是聚簇索引(表的实际顺序),它也可以是二级索引。
  2. 两种语法之间的区别不是优化器可以解决的性能问题,而是正确性。如果您将过滤器放在WHERE 中,您将过滤掉所有没有CustomersStoresON 子句中的过滤器通常是正确的。在内部连接中,它没有任何区别(甚至对性能)。
    要优化此查询,最好将Version 作为索引中的第一列,然后是CustomerNumber。另一种选择是过滤索引,但这超出了这里的范围。

我建议您阅读索引。 Brent Ozar 可能是一个不错的起点,同样Use the Index, Luke

【讨论】:

  • 感谢您的信息。我确实有一本书,我正在努力提高自己的意识。我无权更新表的索引。我只是使用数据创建报告。所以考虑到这一点,如果我有表 A 加入表 b,我应该尝试找到他们共享的索引吗?如果不存在,是加入 A 的索引还是 B 的索引更好?
  • 加入任何正确的字段。不要编造适合索引的东西
猜你喜欢
  • 2021-12-21
  • 2019-08-27
  • 2016-12-10
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-25
  • 2012-08-12
相关资源
最近更新 更多