2016-08-10 1 views
2

У меня странная проблема с моей работой с sql-запросами. Когда я пользуюсь оператором = в ВЗАИМОДЕЙШИЙ ПРИСОЕДИНЕНИЕ запрос занимает около 30,514 минут, но в случае с < И> занимает всего 1,1717 секунд. Это по запросу:SQLITE Operatros "=" comapare с "< AND >" Разница в производительности

-- 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=?) 

запрос с < И> (быстрее)

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, что она должна использовать лучший алгоритм secend в первом запросе?

+0

Показать [EXPLAIN PLAN ЗАПРОСА] (http://www.sqlite.org/eqp.html) выход для обоих запросов. –

+0

Можете ли вы опубликовать схему для таблицы? имеет ли размер индекс? – chugadie

ответ

0

Обновление, сначала я неправильно понял, что сравнение неравенства было намного медленнее. Обычно это то, чего вы ожидаете. Это было не так, так что давайте еще раз взломать его.

С сравнением неравенства Вначале движок должен найти все записи, соответствующие размеру условия> 4095, вполне вероятно, что их будет очень много. Может быть так много совпадений, что было бы бесполезно использовать движок для индекса. Может произойти полное сканирование таблицы.

Но sqlite может использовать только один индекс для таблицы в запросе. Если он не может использовать индекс по размеру, лучше всего использовать индекс в файле. И это нулевое сравнение, вероятно, устраняет большое количество строк, что приводит к более быстрому запросу.

Это намного проще с сравнением равенства, поэтому он использует индекс в поле размера , но это, вероятно, устраняет гораздо меньшее количество строк, чем с другим индексом, равным нулю.

Если это еще не объясняет, вопросы, вы можете обновить свой вопрос, чтобы показать количество возвращаемых записей, количество записей с файлом = 4096 и числом нуля names.

+0

Если я правильно вас понял, запрос с ** = ** должен быть быстрее - это логика; Но в моем случае он медленнее 30 * 60 раз. Зачем? –

+0

имел еще одну трещину. – e4c5

0

Хорошо, теперь он работает с равным сравнением. Я добавил проиндексированных:

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

 Смежные вопросы

  • Нет связанных вопросов^_^