sqlite:"没有查询解决方案"用于覆盖索引时的列!="某事"

时间:2017-07-13 08:50:18

标签: sqlite

以下查询会抛出一个"无查询解决方案"。 aaa1是包含en_meros, en_ref, en_se

的索引
SELECT en_family
FROM entries INDEXED BY aaa1
WHERE (en_meros<>6) AND (en_ref=0) AND (en_se=1) AND (en_lect LIKE "% abcd%" OR en_lect LIKE "abcd%")

如果我将en_meros<>6更改为en_meros=6,那么它可以正常运行,但我正在寻找不等于。

如果我不使用任何索引,则查询速度很慢(约500毫秒)。

如果我使用列en_ref或en_se的各个索引,它仍然是~400ms

我该怎么办?我该如何解决这个问题?

提前谢谢。

编辑:表格的架构是:

CREATE TABLE [entries] (
  [en_id] INT, 
  [en_lect] TEXT(4096), 
  [en_example] TEXT(4096), 
  [en_opref] INT, 
  [en_meros] INT, 
  [en_main] INT, 
  [en_header] INT, 
  [en_se] INT, 
  [en_atono] TEXT(4096), 
  [en_family] INT, 
  [en_ref] INT, 
  [en_lectlexi] TEXT(4096), 
  [en_thama] TEXT(4096), 
  [en_meros2] INT);
CREATE INDEX [aaa1] ON [entries] ([en_meros], [en_ref], [en_se], [en_lect]);
CREATE INDEX [en_atono1] ON [entries] ([en_atono]);
CREATE INDEX [en_family1] ON [entries] ([en_family]);
CREATE INDEX [en_header1] ON [entries] ([en_header]);
CREATE UNIQUE INDEX [en_id1] ON [entries] ([en_id]);
CREATE INDEX [en_lect_en_ref1] ON [entries] ([en_lect], [en_ref]);
CREATE INDEX [en_lect1] ON [entries] ([en_lect]);
CREATE INDEX [en_main1] ON [entries] ([en_main]);
CREATE INDEX [en_meros1] ON [entries] ([en_meros]);
CREATE INDEX [en_meros21] ON [entries] ([en_meros2]);
CREATE INDEX [en_opref1] ON [entries] ([en_opref]);
CREATE INDEX [en_ref1] ON [entries] ([en_ref]);
CREATE INDEX [en_se1] ON [entries] ([en_se]);
CREATE INDEX [en_thama1] ON [entries] ([en_thama]);
CREATE INDEX [en_meros2_en_lect] ON [entries] ([en_meros2], [en_lect]);

2 个答案:

答案 0 :(得分:2)

如查询计划文档(Query PlanningThe SQLite Query Planner)所示,不可能使用索引来搜索具有不等式比较的列值。

INDEXED BY aaa1不会改变这种情况; “没有查询解决方案”意味着根本无法使用该索引,即使是在缓慢的情况下也是如此。

只有两个相等比较可以加速索引,因此您可以通过在这些列上创建索引来获得最大的改进:

CREATE INDEX aaa2 ON entries(en_ref, en_se);

找到索引条目后,仍必须查找相应的表格行。为避免这一额外步骤,您可以创建一个covering index,在查询列之后还包含查询必须读取的所有其他列:

CREATE INDEX aaa3 ON entries(en_ref, en_se, en_lect, en_meros, en_family);

一般情况下,你不应该使用INDEXED BY;仅当查询计划程序在两个索引之间进行选择时才会有用,并且恰好选择了错误的索引。

答案 1 :(得分:0)

一个仍然很慢(~200ms),但比没有指数解决方案更好:

SELECT en_family
FROM entries INDEXED BY aaa1
WHERE (en_meros<6 OR en_meros>6) AND (en_ref=0) AND (en_se=1) AND (en_lect LIKE "% abcd%" OR en_lect LIKE "abcd%")