【问题标题】:Mysql. a multiple-column index exists on col1 and col2, what's the index will be use?mysql。 col1 和 col2 上存在多列索引,将使用什么索引?
【发布时间】:2021-01-31 00:44:06
【问题描述】:

mysql 8.0.21

CREATE TABLE test (
    id         INT NOT NULL,
    last_name  CHAR(30) NOT NULL,
    first_name CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX name (last_name,first_name)
);

sql 为:select * from test where last_name between 'james' and 'jones' and first_name = 'M'

实际上将使用什么索引,(last_name, first_name) 还是只是 2 列索引的一部分

参考:https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html

【问题讨论】:

  • 使用explain,您可以自行查找。
  • 您的表定义中没有 INDEX(last_name),因此您的问题应该改写为是否只使用 2 列索引的一部分。

标签: mysql indexing query-performance


【解决方案1】:

您在(last_name, first_name) 上的索引恰好是covering index。也就是说,数据库服务器可以满足您从索引中的整个查询,而无需回溯表。这通常是性能上的胜利。因此,您的具体问题的答案是,将使用您的两列索引。 (您的 PK id 值自动成为索引的一部分。)

这是一个完美的索引,可以最好地处理您的特定查询吗?

  WHERE first_name = constant AND last_name BETWEEN whatever AND whatelse

,不是。该查询的完美索引将是(first_name, last_name)。该索引使服务器可以使用index range scan 满足您的查询。它找到常量first_name 和第一个匹配的last_name,然后扫描索引到最后一个匹配的last_name。这很快,即使在一张大桌子上也是如此。

@gmb 是正确的。输入EXPLAIN or EXPLAIN ANALYZE right before your SELECT,数据库服务器将为您提供有关它如何满足您的查询的信息。

研究 Marcus Winand 的这一伟大材料:https://use-the-index-luke.com/

【讨论】:

  • 如果向表中添加另一列,则索引将不再“覆盖”。但是,那个索引会继续使用ICP(Index Condition Pushdown)(“使用索引条件”),这有一些好处。
【解决方案2】:

这将是 SELECT:

的最佳索引
INDEX(first_name, last_name)

也许你会想要两者:

INDEX(last_name, first_name)
INDEX(first_name, last_name)

不要同时包含INDEX(last_name)INDEX(first_name);他们混淆了优化器。见http://mysql.rjweb.org/doc.php/find_nearest_in_mysql#bounding_box

在构建最佳索引时,开始使用“=”测试任何列。 (在你的例子中就是first_name。)更多:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

【讨论】:

    猜你喜欢
    • 2016-08-12
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多