Производительность MYSQL "IN"
Я запускаю запрос MYSQL в два этапа. Во-первых, я получаю список идентификаторов с одним запросом, а затем я извлекаю данные для этих идентификаторов, используя второй запрос по строкам SELECT * FROM data WHERE id in (id1, id2 ...)
. Я знаю, что это звучит взломанно, но я сделал это так, потому что запросы очень сложны; первая включает в себя множество геометрии и триггернометрии, вторая - множество разных объединений. Я уверен, что они могут быть написаны в одном запросе, но мой MYSQL недостаточно хорош, чтобы отключить его.
Этот подход работает, но он не чувствует себя хорошо; плюс я обеспокоен тем, что он не будет масштабироваться. В настоящий момент я тестирую базу данных из 10 000 записей с 400 идентификаторами в предложении "IN" (т.е. IN (id1, id2 ... id400)
), и производительность в порядке. Но что, если скажут 1 000 000 записей?
Где узкие места производительности (скорость, память и т.д.) для такого рода запросов? Любые идеи о том, как реорганизовать такой запрос, также являются удивительными. (например, если это необходимо для сохранения хранимых процедур).
Ответы
Ответ 1
Начиная с определенного количества записей предикат IN
над SELECT
становится быстрее, чем над списком констант.
См. эту статью в своем блоге для сравнения производительности:
Если столбец, используемый в запросе в предложении IN
, индексируется, например:
SELECT *
FROM table1
WHERE unindexed_column IN
(
SELECT indexed_column
FROM table2
)
то этот запрос просто оптимизирован для EXISTS
(который использует только одну запись для каждой записи из table1
)
К сожалению, MySQL
не способен выполнять HASH SEMI JOIN
или MERGE SEMI JOIN
, которые еще эффективнее (особенно если индексируются оба столбца).
Ответ 2
Почему вы сначала извлекаете идентификаторы? Вероятно, вы должны просто присоединиться к таблицам. Если вы используете идентификаторы для чего-то еще, вы можете вставить их в таблицу temp раньше и использовать эту таблицу для соединения.