在以下两种情况下:
create table `Table` (
`id` int(10),
`column1` int(10),
`column2` int(10),
KEY (`column2`)
);
和
create table `Table` (
`id` int(10),
`column1` int(10),
`column2` int(10),
KEY (`column1`, `column2`)
);
现在考虑查询select * from Table where column2=xxx;
是否有可能第二种场景会比第一种场景更快,例如,在行恰好密集地聚集在列n1上的情况下?
或者我们可以100%肯定地说,第一种情况总是至少和第二种情况一样快?
我试着搜索复合/复合键速度,但与单一键相比,无法找到100%确定的答案。
第二种方案是否有可能比第一种方案更快
是的。
该表的统计信息非常不正确,导致服务器错误地使用索引而不是表扫描。例如,统计数据显示大约1%的行包含值xxx
,而实际上是50%。
当然,这种情况发生的可能性极低,但也不是零。
ANALYZE TABLE
将修复此问题。
阅读此处:https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html
您的第一个索引将更快,因为查询将是索引扫描。复合索引实际上会导致查询成为慢行的扫描。只有当您要查找的列位于索引的最左侧时,才会使用索引。因为column2不是最左边的,所以你的索引不会被使用。
复合索引只用于如下查询:
- select * from Table where column1='X'
- select * from Table where column1='X' and column2='Y'
使用索引最重要的是知道如何查询数据。如果你不知道,过早地优化可能对你没有任何好处。
文字回答:100%不能保证;还"single-column"与"composite"不是正确的问题,正如埃里克指出的。
实际回答:对于where column2=xxx
,您应该有一个以column2
开头的索引。
长答:
数据库引擎在"缓存"方面应用了很多智能。索引和数据。目标是使典型的查询速度平均。
如果没有太多的"chunn",数据块和索引将被放入RAM("buffer_pool"),并且它们驻留在那里。重启后的第一个查询将不得不做一些I/O来从磁盘获取块;这是缓慢的。后续查询可以跳过部分或全部读取;因此它们更快。也就是说,其他查询可以碰巧使_this查询更快。因此,100%的人被打败了。(没有办法做到"100%"。而不是把一切都放慢到一个恒定的,但效率低下的速度
关于创建最优索引的更多信息:http://mysql.rjweb.org/doc.php/index_cookbook_mysql
让我把事情弄得更混乱。在特定的3列表中,使用特定的SELECT *
,以下是通常的排序顺序;从最慢到最快
INDEX(column2, column1) -- index's BTree is bulkier than the next
INDEX(column2) -- good (and recommended)
INDEX(column2, column1, id) -- "covering" all of "*" is in the index
在构建索引时,最好将所有重要的查询(Select、Update、Delete)收集在一起,以决定使用哪一组索引。