覆盖索引并不等同于复合索引。
如果我在col3和col4上分别创建了两个独立的索引,那么在这个查询中会使用哪一个索引?
会使用基数最高的索引。
MySQL会统计每个索引的属性。
使用具有最大区分度的索引(如MySQL的统计数据所示)。
我在某处读到,对于查询中的每个表只使用一个索引。这意味着查询无法同时使用两个索引吗?
您可以使用子查询。
或者更好的方法是使用包含col3和col4的复合索引。
其次,如果我创建了一个复合索引,将col3和col4组合在一起,但只在WHERE子句中使用了col3,那么性能会更差吗?例如:
复合索引
正确术语是 compound
索引,而不是 composite 索引。
只有复合索引的左边部分会被使用。
因此,如果索引定义为:
index myindex (col3, col4) <<-- will work with your example.
index myindex (col4, col3) <<-- will not work.
请参考:
http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html。
请注意,如果您选择最左边的字段,在where子句中不使用该部分索引也可以实现查询。
假设我们有一个复合索引。
Myindex(col1,col2)
SELECT col1 FROM table1 WHERE col2 = 200 <<
SELECT * FROM table1 where col2 = 200 <<
这样做可行的原因是第一个查询使用了覆盖索引并对其进行了扫描。
第二个查询需要访问表格,因此通过索引进行扫描是没有意义的。
这仅适用于InnoDB。
什么是覆盖索引
当查询中选择的所有字段都被索引“覆盖”时,称为覆盖索引。在这种情况下,InnoDB(而不是MyISAM)永远不会读取表中的数据,而只使用索引中的数据,从而显著加速选择操作。
请注意,在InnoDB中,主键包含在所有二级索引中,因此所有二级索引都是复合索引。
这意味着如果在InnoDB上运行以下查询:
SELECT indexed_field FROM table1 WHERE pk = something
MySQL将始终使用覆盖索引,而不会访问实际表。虽然它可能使用覆盖索引,但它更喜欢使用PRIMARY KEY
,因为它只需要命中一行。
select * from table1 where col2 = 200
不会使用索引,但是当我运行上述测试时,explain
显示索引确实被使用了。你用的是哪个操作系统? - Pacerier