如果列已经自己编入索引,那么创建多列索引是否有帮助?

时间:2018-06-01 03:54:13

标签: sql database indexing sqlite

假设您的表有三列:

  1. 时间(整数)
  2. name(varchar)
  3. other_column(varchar)
  4. 你有两个索引:

    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);
    

2 个答案:

答案 0 :(得分:1)

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

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

使用以下代码进行简短的游戏,您可以将其作为充分探索的基础(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_table USE TEMP B-TREE for ORDER BY
  • 仅使用第一个索引 SCAN TABLE my_table USING INDEX index_time USE TEMP B-TREE for ORIGHT PART OF ORDER BY
  • 使用第一个和第二个 SCAN TABLE my_table使用INDEX index_time USE TEMP B-TREE用于订购的正确部分。
  • 只有第二个 SCAN TABLE my_table USE TEMP B-TREE for ORDER BY
  • 使用全部3 SCAN TABLE my_table使用INDEX index_time USE TEMP B-TREE以获得正确的部分
  • 只有第3个 SCAN TABLE my_table USE TEMP B-TREE for ORDER BY

第4个查询

  • 没有任何 SCAN TABLE my_table USE TEMP B-TREE for ORDER BY
  • 使用1 SCAN TABLE my_table USE TEMP B-TREE for ORDER BY
  • 使用1和2 SCAN TABLE my_table使用INDEX index_name USE TEMP B-TREE以获得正确的部分
  • 使用2 SCAN TABLE my_table使用INDEX index_name USE TEMP B-TREE以获得正确的部分
  • 使用1,2和3 SCAN TABLE my_table使用INDEX index_name_and_time
  • 只有3 SCAN TABLE my_table使用INDEX index_name_and_time

当然,由于表格是空的,因此不会考虑时间因素。上面的代码可以很容易地适应包括数据,从而应用时间。请注意,您也可以考虑除运行查询之外的其他效果,例如可能会改变索引的插入和删除。

答案 - 取决于。

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

答案 1 :(得分:0)

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

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