在以下查询中
SELECT col1,col2
FROM table1
WHERE col3='value1'
AND col4='value2'
如果我在col3上有一个单独的索引,而在col4上有另一个索引,那么在这个查询中将使用哪一个?
我在某处读到,对于查询中的每个表,只使用一个索引.这是否意味着查询无法使用这两个索引?
其次,如果我同时使用col3和col4创建了一个复合索引,但在WHERE子句中只使用了col3,那么性能会更差吗?
例:
SELECT col1,col2
FROM table1
WHERE col3='value1'
最后,在所有情况下使用覆盖索引是否更好? MYISAM和innodb存储引擎有什么不同?
解决方法:
覆盖索引与复合索引不同.
If I have 2 separate indexes one on col3 and the other on col4, Which one of them will be used in this query ?
具有最高基数的索引.
MySQL会统计哪些索引具有哪些属性.
将使用具有最大辨别力的索引(在MySQL的统计中显而易见).
I read somewhere that for each table in the query only one index is used. Does that mean that there is no way for the query to used both indexes ?
您可以使用子选择.
或者甚至更好地使用包含col3和col4的复合索引.
Secondly, If I created a composite index using both col3 and col4 together but used only col3 in the WHERE clause will that be worse for the performance? example:
复合指数
正确的术语是复合指数,而不是复合指数.
仅使用复合索引的最左侧部分.
因此,如果索引定义为
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 <<-- will use index
SELECT * FROM table1 where col2 = 200 <<-- will NOT use index.
这样做的原因是第一个查询使用覆盖索引并对其进行扫描.
第二个查询需要访问该表,因此扫描索引没有意义.
这仅适用于InnoDB.
什么是覆盖指数
覆盖索引是指在查询中选择的所有字段都被索引覆盖的情况,在这种情况下,InnoDB(不是MyISAM)将永远不会读取表中的数据,而只会使用索引中的数据,从而显着加快选择.
请注意,在InnoDB中,主键包含在所有二级索引中,因此所有二级索引都是复合索引.
这意味着如果您在InnoDB上运行以下查询:
SELECT indexed_field FROM table1 WHERE pk = something
MySQL将始终使用覆盖索引,不会访问实际的表.