1

在以下两种情况下:

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;

第二种情况是否有可能比第一种情况更快,例如在行恰好在 column1 上密集聚集的情况下?

或者我们可以 100% 肯定地说,第一种情况总是至少和第二种情况一样快?

我尝试搜索复合/复合键速度,但与单键相比,找不到 100% 确定的答案。

4

3 回答 3

1

字面答案:不能保证100%;正如 Erik 指出的那样,“单列”与“复合”也不是正确的问题。

实用答案:给定where column2=xxx,您应该有一个以.开头column2的索引。

长答案:

数据库引擎将大量智能应用于“缓存”索引和数据。目标是使典型查询平均快速。

如果没有太多的“流失”,数据块和索引就会被带入 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)收集在一起,以决定拥有哪一组索引。该问题仅针对该特定模式解决了一个特定选择。

于 2021-08-05T19:37:16.387 回答
1

在这里阅读: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'

索引最重要的是知道您将如何查询数据。如果您不知道,过早优化可能对您没有任何好处。

于 2021-08-05T11:14:18.293 回答
1

第二种情况是否有可能比第一种情况更快

是的。

这是当表统计信息非常不正确以至于服务器错误地使用索引而不是表扫描时的情况。例如,统计数据显示大约 1% 的行包含该值xxx,而实际为 50%。

当然,这种情况的概率极低,但也不是零。

ANALYZE TABLE将解决此问题。

于 2021-08-05T11:18:50.967 回答