MySQL INDEX在不同的列上连接相同的表

时间:2016-02-23 20:36:30

标签: mysql join indexing

我的数据集的简化版本:

我有一个包含2列col1col2

的表格

我想优化此查询:

SELECT * FROM mytable a
LEFT JOIN mytable b
ON a.col1 = b.col2

在此表上创建的最佳索引是什么?

  • 两个索引:col1上的索引和col2
  • 上的另一个索引
  • 一个双重索引:col1,col2
  • 上的索引

让我们稍微复杂一点:(我的现实生活中的数据结构)

假设我的表格中还有一列extract_date

SELECT * FROM mytable a
LEFT JOIN mytable b
ON a.col1 = b.col2 AND a.extract_date=b.extract_date

在此表上创建的最佳索引是什么?

  • 两个双重索引:col1,extract_date上的index1和col2,extract_date上的另一个
  • 一个三重索引:col1,col2,extract_date
  • 上的索引

3 个答案:

答案 0 :(得分:2)

  

在此表上创建的最佳索引是什么?

     
      
  • 两个索引:col1上的索引和col2
  • 上的另一个索引   
  • 一个双重索引:col1,col2
  • 上的索引   

两列索引不会像两个单列索引那样优化查询。

From MySQL manual,大胆强调我的:

  

对于测试索引中所有列的查询,或者只测试第一列的查询,前两列,前三列等,MySQL可以使用多列索引 。如果在索引定义中以正确的顺序指定列,则单个复合索引可以加速同一表上的多种查询。

从上面的内容可以看出,当前导(最左侧)列存在约束时,MySQL引擎可以使用多列索引。

因此,您的特定查询不会受益于col1,col2上的索引和两个单独的索引,因为考虑到= b.col2部分JOIN,此索引不会用于查找条款。

SELECT * FROM mytable a
LEFT JOIN mytable b
ON a.col1 = b.col2

至于你的真实"数据结构,以上仍然适用。

注意:经验法则是首先索引相等,然后索引范围。 Markus Winand 支持我处理索引的his book

答案 1 :(得分:1)

对于a.col1 = b.col2,col1 and col2`位于单独的表中。 (不要紧,它是一个自连接;这与创建索引无关。)

对于更复杂的查询,请再次分别考虑每个表。这些是最佳的:

INDEX(col1, extract_date) -- in either order, and
INDEX(col2, extract_date) -- also in either order.

我同意马库斯并考虑;看我的Index Cookbook。并且你只能在'范围'获得一个裂缝。

答案 2 :(得分:0)

你应该有两个索引。只有当WHERE子句的格式为

时,才能使用复合索引中的所有列
WHERE a.col1 = something AND a.col2 = somethingelse AND a.col3 = thirdthing ...

a.col1 = b.col2之类的条件与该模式不匹配,因为ab是表格的不同实例。