在以下查询中
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存储引擎有什么不同?
答案 0 :(得分:41)
覆盖索引与复合索引不同。
如果我在col3上有一个单独的索引,而在col4上有另一个索引,那么在这个查询中将使用哪一个?
基数最高的索引 MySQL会统计哪些索引具有哪些属性 将使用具有最大区分能力的索引(如MySQL的统计数据中所示)。
我在某处读到,对于查询中的每个表,只使用一个索引。这是否意味着查询无法使用这两个索引?
您可以使用子选择 或者甚至更好地使用包含col3和col4的复合索引。
其次,如果我同时使用col3和col4创建了一个复合索引,但在WHERE子句中只使用了col3,那么性能会更差吗?例如:
复合指数
正确的术语是compound
索引,而不是复合词
仅使用复合索引的最左侧部分
因此,如果索引定义为
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。
什么是覆盖指数
覆盖索引是指在查询中选择的所有字段都是covered
索引的情况,在这种情况下,InnoDB(不是MyISAM)永远不会读取表中的数据,而只会使用索引中的数据,显着加快了选择。
请注意,在InnoDB中,主键包含在所有二级索引中,因此所有二级索引都是复合索引
这意味着如果您在InnoDB上运行以下查询:
SELECT indexed_field FROM table1 WHERE pk = something
MySQL将始终使用覆盖索引,不会访问实际的表。
答案 1 :(得分:5)
我赞成Johan's answer表示完整性,但我认为他对二级索引的陈述不正确和/或令人困惑;
Note that in InnoDB the primary key is included in all secondary indexes,
so in a way all secondary indexes are compound indexes.
This means that if you run the following query on InnoDB:
SELECT indexed_field FROM table1 WHERE pk = something
MySQL will always use a covering index and will not access the actual table.
虽然我同意辅助索引中的主键是 INCLUDED ,但我不同意MySQL“将始终在此处指定的SELECT查询中使用覆盖索引”。
要了解原因,请注意在这种情况下始终需要完整索引“扫描” 。这与“搜索”操作不同,而是对二级索引内容的100%扫描。这是因为主键的二级索引未订购;它按“indexed_field”排序(否则它不会用作索引!)。
鉴于后一个事实,在某些情况下,“寻找”主键,然后从“实际表”中提取indexed_field,而不是从二级索引中提取效率更高。
答案 2 :(得分:1)
这是一个我经常听到的问题,由于以下问题引起了很多混淆:
多年来mySQL的差异。 多年来索引和多索引支持发生了变化(得到支持)
InnoDB / myISAM的差异 有一些关键的区别(下面),但我不相信多个索引是其中之一
MyISAM较老但经过验证。 MyISAM表中的数据分为三个不同的文件: - 表格格式,数据和索引 InnoDB比MyISAM相对更新,并且交易安全。 InnoDB还提供行锁定而不是表锁定,这增加了多用户并发性和性能。 InnoDB也有外键约束 由于其行锁定功能,InnoDB非常适合高负载环境。
为了确保事情,请务必使用explain_plan来分析查询执行情况。
答案 3 :(得分:0)
复合索引与复合索引不同。