以下查询会抛出一个"无查询解决方案"。
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]);
答案 0 :(得分:2)
如查询计划文档(Query Planning和The 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%")