【问题标题】:Is it helpful to create a multi-column index if the columns are already indexed on their own?如果列已经自己建立索引,那么创建多列索引是否有帮助?
【发布时间】:2018-11-11 03:36:21
【问题描述】:

假设您的表格有三列:

  1. 时间(整数)
  2. 名称(varchar)
  3. other_column (varchar)

你有两个索引:

CREATE INDEX index_time ON my_table (time);
CREATE INDEX index_name ON my_table (name);

在这种情况下,如果我根据时间和名称创建一个新索引,会有什么不同吗?即:

CREATE INDEX index_name_and_time ON my_table (name,time);

【问题讨论】:

    标签: sql database indexing sqlite


    【解决方案1】:

    第三个索引(name, time)(name) 是冗余的。

    您可能应该删除 (name) 索引,只包括 (name, time)(time) -- 如果这些是您认为需要的索引。

    【讨论】:

      【解决方案2】:

      就整体性能而言,这三个索引可能会过大,并且在插入时会产生不利影响,因为要维护三个索引以及额外的内存/空间利用率。

      但是,第一个因素是确定是否实际使用索引,这取决于要运行的查询。

      从使用以下代码的简短游戏中,您可以将其用作更全面探索的基础(EXPLAIN QUERY PLAN your_query 是一个使用工具):-

      DROP TABLE IF EXISTS my_table;
      DROP INDEX IF EXISTS index_time;
      DROP INDEX IF EXISTS index_name;
      DROP INDEX IF EXISTS index_name_and_time;
      CREATE TABLE IF NOT EXISTS my_table (time INTEGER, name TEXT, other TEXT);
      
      CREATE INDEX IF NOT EXISTS index_time ON my_table (time); -- INDEX 1
      -- CREATE INDEX IF NOT EXISTS index_name ON my_table (name); -- INDEX 2
      -- CREATE INDEX index_name_and_time ON my_table (name,time); -- INDEX 3
      
      EXPLAIN QUERY PLAN
      SELECT * FROM my_table; -- QUERY 1
      
      -- EXPLAIN QUERY PLAN 
      -- SELECT time, name, other FROM my_table -- QUERY 2
      
      -- EXPLAIN QUERY PLAN
      -- SELECT time, name, other FROM my_table ORDER BY time, name; -- QUERY 3 
      
      -- EXPLAIN QUERY PLAN 
      -- SELECT time, name, other FROM my_table ORDER BY name, time; -- QUERY 4
      

      可以得到以下结果:-

      前两个查询,没有优势,只有劣势。

      没有索引到拥有所有 3 个索引对前 2 个查询没有影响(基本相同)。 当有 0、1、2 或 3 个索引可用时,不使用任何索引。 他们使用 SCAN TABLE my_table

      第三次查询

      • 如果没有任何索引,则 SCAN TABLE my_tableUSE TEMP B-TREE FOR ORDER BY
      • 只有第一个索引 SCAN TABLE my_table USING INDEX index_timeUSE TEMP B-TREE FOR RIGHT PART OF ORDER BY
      • 使用第一个和第二个 SCAN TABLE my_table USING INDEX index_timeUSE TEMP B-TREE FOR RIGHT PART OF ORDER BY
      • 只有第二个 SCAN TABLE my_tableUSE TEMP B-TREE FOR ORDER BY
      • 所有 3 个 SCAN TABLE my_table USING INDEX index_timeUSE TEMP B-TREE FOR RIGHT PART OF ORDER BY
      • 只有第三个 SCAN TABLE my_tableUSE TEMP B-TREE FOR ORDER BY

      第四次查询

      • 没有任何 SCAN TABLE my_tableUSE TEMP B-TREE FOR ORDER BY
      • 有 1 个 SCAN TABLE my_tableUSE TEMP B-TREE FOR ORDER BY
      • 使用 1 和 2 SCAN TABLE my_table USING INDEX index_nameUSE TEMP B-TREE FOR RIGHT PART OF ORDER BY
      • 有 2 个 SCAN TABLE my_table USING INDEX index_nameUSE TEMP B-TREE FOR RIGHT PART OF ORDER BY
      • 使用 1,2 和 3 扫描表 my_table USING INDEX index_name_and_time
      • 只有 3 个 SCAN TABLE my_table USING INDEX index_name_and_time

      当然,这不考虑时间,因为桌子是空的。上面的代码可以很容易地适应包含数据,因此可以应用时间。请注意,您可能还需要考虑运行查询以外的影响,例如会改变索引的插入和删除。


      答案 - 视情况而定。

      因此,至少从索引利用率的角度来看,索引是否有用取决于所使用的查询。

      【讨论】:

        猜你喜欢
        • 2015-01-23
        • 1970-01-01
        • 2016-01-10
        • 1970-01-01
        • 2021-11-30
        • 2018-12-14
        • 2012-11-27
        • 2012-06-01
        • 2023-03-23
        相关资源
        最近更新 更多