我的SQL查询性能出现了一个奇怪的问题。当我在 LEFT JOIN 中使用运算符 = 时,查询大约需要30.514分钟,但是在< AND> 只需1.717秒。这是查询:
-- 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 QUERY PLAN:
查询 = (慢)
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=?)
使用&lt;查询AND&gt; (更快)
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 :(得分:0)
更新,起初我误读了这个不平等比较慢得多。这通常是人们所期望的。情况并非如此,所以让我们再看一次。
使用不等式比较引擎首先必须找到符合条件大小&gt;的所有记录。 4095很可能会有很多。可能有这么多匹配,引擎使用索引是徒劳的。可能会发生全表扫描。
但是sqlite在查询中每个表只能使用一个索引。如果它不能在大小上使用索引,最好的方法是使用文件索引。这种空比较可能会消除大量行,从而导致更快的查询。
使用相等比较更简单,因此它看起来使用大小字段上的索引,但这可能会消除比其他索引更少的行数为空。
如果这仍然无法解释问题,您是否可以更新您的问题以显示返回的记录数, file = 4096 的记录数和null names
的数量。
答案 1 :(得分: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