【问题标题】:Separate Join clause in a Composite Index复合索引中的单独连接子句
【发布时间】:2012-10-21 08:21:43
【问题描述】:

有一个综合指数对这样的事情有好处吗:

SELECT * FROM a INNER JOIN b ON(a.id=b.id)
                INNER JOIN c ON(a.bar=c.id)
                INNER JOIN d ON(a.foo=d.id)

索引是:

(a.id, a.bar, a.foo)

【问题讨论】:

    标签: mysql composite-index


    【解决方案1】:

    只会使用索引的前沿 (a.id),因此只有 INNER JOINb 会从索引中受益...所以索引中的附加列(a.bar 和 @ 987654326@) 在发布的示例查询中无益。

    From the MySql documentation:

    如果列不使用,MySQL 不能使用索引来执行查找 形成索引的最左侧前缀。假设您有SELECT 此处显示的语句:

    SELECT * 
    FROM tbl_name 
    WHERE col1=val1; 
    
    SELECT * 
    FROM tbl_name 
    WHERE col1=val1 AND col2=val2;
    
    SELECT * 
    FROM tbl_name 
    WHERE col2=val2; 
    
    SELECT * 
    FROM tbl_name 
    WHERE col2=val2 AND col3=val3; 
    

    如果(col1, col2, col3) 上存在索引, 只有前两个查询使用索引。第三个和第四个查询 确实涉及索引列,但 (col2)(col2, col3) 不涉及 (col1, col2, col3) 的最左边前缀。

    【讨论】:

      【解决方案2】:

      JOINing(即INNER JOIN,而不是LEFT JOIN)时,优化器将选择任何表作为“第一个”表。然后它将使用ON 子句移动到下一个表并执行“NLJ”(嵌套循环连接)以进入第二个表。等等。

      通常,当有 WHERE 子句(或某些其他内容)时,它将确定哪个表是“第一个”。否则,优化器通常会选择最小的表。

      给定一张表上的WHERE 子句,它将寻找“最佳”INDEX 来使用。这样的索引很可能在WHERE 子句中涉及一个或多个列。两个索引不会(极少数例外)同时用于单个表。

      当移动到“下一个”表时,可能ON 子句中的列上的索引确定最佳索引。请注意,如果您有ON a.x=b.x AND a.y=b.y,则需要复合INDEX(x,y)(任意顺序)。

      回到不决定从哪个表“开始”的情况......优化器将为该表尝试各种顺序。对于每个不同的排序,都有一组不同的索引。

      为此

           FROM a 
           INNER JOIN b ON(a.id=b.id)
           INNER JOIN c ON(a.bar=c.id)
           INNER JOIN d ON(a.foo=d.id)
      

      这些是最优的,但我们不一定能预测会使用哪个:

      a:  (id)  -- if coming from b
      a:  (bar) -- if coming from c
      a:  (foo) -- if coming from d
      b:  (id)  -- if coming from b 
      c:  (id)  -- if coming from a
      d:  (id)  -- if coming from a
      

      注意:您可能已经在每个表中添加了PRIMARY KEY(id),因此无需添加INDEX(id)

      你说SELECT *,意思是你想要所有四个表中的所有列。如果情况并非如此,我们可以讨论另一种优化:“覆盖索引”。

      更多讨论:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

      【讨论】:

        猜你喜欢
        • 2017-02-08
        • 2012-01-09
        • 2011-01-01
        • 1970-01-01
        • 2011-03-25
        • 2019-12-13
        • 2017-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多