2016-08-10 24 views
2

我的SQL查詢性能有一個奇怪的問題。當我在使用運營商= LEFT JOIN查詢約需30.514分鐘秒,但如果與< AND>只需要1.717秒。這是通過查詢:SQLITE操作「=」與「< AND >」的性能差異comapare

-- data_filehash.size>4095 AND data_filehash.size<4097 || 1.717 seconds 
SELECT files.*, data_filehash.* 
FROM v_filesp AS files 
LEFT JOIN data_filehash ON files.id = data_filehash.file AND data_filehash.size>4095 AND data_filehash.size<4097 
WHERE data_filehash.file IS NULL 

-- data_filehash.size=4096 || 30.515 minutes 
SELECT files.*, data_filehash.* 
FROM v_filesp AS files 
LEFT JOIN data_filehash ON files.id = data_filehash.file AND data_filehash.size=4096 
WHERE data_filehash.file IS NULL 

結果總是相同的(33016記錄在我的數據庫中); v_filep是一個視圖;我在data_filehash.size,data_filehash.file和文件主鍵(v_filesp).id上有索引;

我認爲這是不正常的。也許我應該配置一些東西,否則我不明白。

有EXPLAIN查詢計劃這兩個查詢:

查詢王氏=(慢)

SEARCH TABLE files USING INDEX files_c_dup (c_dup=?) 
SEARCH TABLE dirs USING INTEGER PRIMARY KEY (rowid=?) 
SEARCH TABLE data_filehash USING INDEX index_size (size=?) 

查詢與< AND>(快)

SEARCH TABLE files USING INDEX files_c_dup (c_dup=?) 
SEARCH TABLE dirs USING INTEGER PRIMARY KEY (rowid=?) 
SEARCH TABLE data_filehash USING INDEX index_file (file=?) 

末步驟是不同的,但它意味着什麼。如何告訴db,她應該在第一個查詢中使用更好的算法?

+0

顯示了兩個查詢[解釋查詢計劃](http://www.sqlite.org/eqp.html)輸出。 –

+0

你可以發佈表的模式嗎?大小是否有索引? – chugadie

回答

0

更新,起初我誤解這是不平等比較慢得多。這通常是人們所期望的。事實並非如此,所以讓我們再來看看它。

隨着不平等的比較引擎首先必須找到匹配條件大小> 4095的所有記錄,這很可能會有很多。可能有如此多的匹配,以致引擎使用索引是徒勞的。全表掃描可能會發生。

但sqlite只能在查詢中爲每個表使用一個索引。如果它不能在大小上使用索引,最好的辦法是使用文件索引。而這種空比較可能會消除導致更快查詢的大量行。

它比平等比較更簡單,因此它看起來使用大小字段上的索引,但這可能會消除比其他索引爲null更少的行數。

如果這還不能解釋的問題,您可以更新您的問題,顯示的返回記錄的數量,記錄的數量與文件= 4096和數量空names的。

+0

如果我正確理解你,用** = **查詢應該更快 - 它是邏輯;但在我的情況下,它是較慢的30 * 60倍。爲什麼? –

+0

有另一個裂縫。 – e4c5

0

好吧,現在它與平等比較正確地工作。我加入INDEXED BY

SELECT files.*, data_filehash.* 
FROM v_filesp AS files 
LEFT JOIN data_filehash INDEXED BY index_file 
ON files.id = data_filehash.file AND data_filehash.size=4096 
WHERE files.c_dup=1 AND data_filehash.file IS NULL 

由於e4c5