【问题标题】:3 column index for search on the 1st and the 3rd columns?用于搜索第一列和第三列的 3 列索引?
【发布时间】:2015-12-29 03:14:40
【问题描述】:

假设我有一个索引 (col1, col2, col3),它可以对这些查询启用索引搜索:

WHERE col1 = xxx
WHERE col1 = xxx AND col2 = yyy
WHERE col1 = xxx AND col2 = yyy AND AND col3 = zzz

如果我想搜索

WHERE col2 = yyy AND col3 = zzz
WHERE col3 = zzz

我必须创建这些索引:

(col2, col3)
(col3)

对吗?

但是如果我想通过以下方式搜索,是否必须创建另一个索引:

WHERE col1 = yyy AND col3 = zzz

?

我试图搜索答案,但没有找到关于在索引中搜索非连续列的信息,例如 here

MySQL 是使用 (col1, col2, col3) 还是我必须创建 (col1, col3)?

【问题讨论】:

    标签: mysql database indexing


    【解决方案1】:

    如果表有一个多列索引,任何最左边的前缀 优化器可以使用索引来查找行。例如,如果 您在 (col1, col2, col3) 上有一个三列索引,您已编制索引 (col1)、(col1, col2) 和 (col1, col2, col3) 的搜索功能。

    如果 列不使用,MySQL 不能使用索引来执行查找 形成索引的最左边前缀。假设你有 此处显示的 SELECT 语句:

    SELECT * FROM tbl_name WHERE col1=val1;
    SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
    
    SELECT * FROM tbl_name WHERE col2=val2;
    SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
    

    如果 (col1, col2, col3) 上存在索引,则只有前两个查询 使用索引。第三个和第四个查询确实涉及索引 列,但 (col2) 和 (col2, col3) 不是 (col1, col2, col3)。

    也就是说,我已经在 >7,000 行表 (InnoDB) 上测试了一些案例。如示例中将列重命名为col1-3,并仅创建主ID索引和多列索引:

    指数:

    以下说明显示 col1、2 和 3 的所有组合都在使用索引:




    因此,一旦存在索引,请随意使用任何列组合,因为它将用于列的 power set 中设置的任何列。


    最后,另一列没有索引,没有使用索引:


    来源:

    【讨论】:

    • 我认为带有 col1,col3 搜索的explain 是有序的,有足够的行数甚至允许使用索引(即:不是 10 行)
    • 但是SELECT * FROM tbl_name WHERE col1=val1 AND col3=val3; 呢?它不会使用(col1,col2,col3)?或者部分只使用col1 部分?还是完全使用col1col3
    • 你只有通过测试才能知道,因为手册页是模棱两可的
    【解决方案2】:

    最左边当然很重要,但下面显示在 col1,col3 搜索的情况下,索引 IS 使用了一个点,然后 where 接管,如在explain 输出中看到

    create table t1
    (   id int auto_increment primary key, -- for sanity sake for tweaks
        col1 int not null,
        col2 int not null,
        col3 int not null,
        key (col1,col2,col3)
    );
    

    -- 我只是在存储过程中运行它以生成足够的行以使任何索引都有用 -- 表示mysql不会在小表上使用索引,稍后参考

    运行几百次:

    insert t1 (col1,col2,col3) values (rand()*1000,rand()*1000,rand()*1000);
    

    好的,现在我们有足够的数据。下面的第三个显示使用了索引,直到一个点(那个点是col1),然后恢复一个where找到col3

    explain select id from t1 where col1=7 and col2=9;
    +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref         | rows | Extra       |
    +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
    |  1 | SIMPLE      | t1    | ref  | col1          | col1 | 8       | const,const |    1 | Using index |
    +----+-------------+-------+------+---------------+------+---------+-------------+------+-------------+
    
    explain select id from t1 where col1=7 and col2=9 and col3=8;
    +----+-------------+-------+------+---------------+------+---------+-------------------+------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref               | rows | Extra       |
    +----+-------------+-------+------+---------------+------+---------+-------------------+------+-------------+
    |  1 | SIMPLE      | t1    | ref  | col1          | col1 | 12      | const,const,const |    1 | Using index |
    +----+-------------+-------+------+---------------+------+---------+-------------------+------+-------------+
    
    explain select id from t1 where col1=7 and col3=8;
    +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra                    |
    +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
    |  1 | SIMPLE      | t1    | ref  | col1          | col1 | 4       | const |    1 | Using where; Using index |
    +----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
    

    外卖

    在 col1,col3 搜索中,技术上 (col1,col2,col3) 组合是通过 col1 使用的

    【讨论】:

      【解决方案3】:
      (col1, col2, col3)
      (col2, col3)
      (col3, col1)
      

      将涵盖 for you describe 的 1、2 或 3 列查询的所有组合(“=”表示每个测试,AND'd 一起)。

      逻辑:

      1. 对于给定的 SELECT,为所有使用“=”测试的列建立索引。列可以按任何顺序排列。

      我展示的 3 个索引经过了一些试验。 (某些其他变体同样有效。)

      警告:如果您还有OR、范围、IN(...)GROUP BYORDER BY 等,我的回答可能不是最佳的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-15
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多