Mysql覆盖vs复合vs列索引

在以下查询中

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将始终使用覆盖索引,不会访问实际的表.

上一篇:mysql-IN子句不使用索引


下一篇:在Python中索引浮点值