2017-07-13 38 views
0

以下查詢引發「無查詢解決方案」。 AAA1是包含en_meros, en_ref, en_sesqlite:「無查詢解決方案」覆蓋索引當列!=「東西」

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<>6en_meros=6然後它的索引,但我在尋找不相等。

如果我不使用任何索引,則查詢速度很慢(〜500 ms)。

如果我使用的列個別指標en_ref或en_se,它仍然是400毫秒〜

我應該怎麼辦?我該如何解決這個問題?

預先感謝您。

編輯:表的模式是:

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

也許是因爲'en_meros <> 6'的行數多於'en_meros = 6'的行數,因此需要時間來獲取這些行? –

+0

MySQL和SQLite是兩種不同的rdbms產品。請只使用相關的產品標籤。 – Shadow

+0

盲目進行隨機更改沒有用。顯示數據庫模式。 –

回答

2

由於查詢規劃文件中所示(Query PlanningThe SQLite Query Planner),因此不可能使用索引來搜索具有不等式比較的列值。

書寫INDEXED BY aaa1不會改變那個; 「沒有查詢解決方案」意味着根本不可能使用該索引,甚至不是以一種緩慢的方式。只有


兩個相等比較可以加快與索引,所以您可以通過創建這些colums指數得到最大的改進:

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

一般情況下,你不應該使用 ;僅當查詢規劃器在兩個索引之間進行選擇時纔有用,並且恰好選擇了錯誤的索引。

+0

將'en_meros'(一個int)放在索引中的'en_lect'(一個字符串)之前是否可能有所作爲?在這裏和SQLite郵件列表中,一般的「好建議」是首先放置「小」列,但由於在索引搜索過程中不會使用,所有字段都將被讀取,可能不會。 – TripeHound

+0

只有當後面的列沒有被實際讀取,並且如此之大以致它們溢出頁面時,這將會有所作爲。 –

0

一個仍然緩慢(〜200毫秒),但總比沒有索引更好的解決方案是:

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%")