Есть ли смысл использовать LIMIT в запросе EXISTS?
Есть ли какой-то выигрыш в производительности при добавлении LIMIT
для EXISTS
запрос, или MySQL будет применять ограничение самостоятельно?
Пример:
IF EXISTS (
SELECT 1
FROM my_table
LIMIT 1 -- can this improve performance?
)
THEN ... END IF;
4 ответа
Цель EXISTS()
должен выполнить запрос только до тех пор, пока он не сможет решить, есть ли какие-либо строки в этой таблице, соответствующие WHERE
пункт. То есть он логически делает то же самое, что и LIMIT 1
, EXISTS
вероятно называется semi-join
в некоторых кругах.
Итог: не использовать LIMIT 1
внутри EXISTS()
,
Немного поигравшись с моим запросом, я заметил, что EXISTS
по-прежнему возвращает 1, если LIMIT
установлено на 0. Я предполагаю, что это означает, что он игнорируется.
Это зависит от того, сколько записей в вашей таблице (my_table). Если записей не слишком много, то вы не увидите никакого улучшения производительности, но если в вашей таблице слишком много записей, то вы увидите улучшение производительности, но это также будет зависеть от многих факторов. как и у вас есть индекс в столбце, который используется в select(если вы сделаете это, вы также получите преимущество от покрытия индекса).
Прошло много времени с момента подачи вопроса. Если кому-то понадобится обходной путь, я публикую решение.
Как обсуждалось выше, ограничение снимается в блоке EXISTS. Однако если мы используем подзапрос в качестве основного запроса EXISTS, мы можем применить LIMIT к подзапросу. В этом случае подзапрос работает как LATERAL, предоставляя данные для условия.
SELECT
...
FROM
your_table AS outer_table
WHERE
...
AND EXISTS (
SELECT
1
FROM (
-- This subquery is working as a LATERAL, so follow the same structure.
SELECT
condition_row
FROM
inner_table
WHERE
...
-- Make sure the subquery is referencing the required entries. (for example if the result blunges to the same account)
AND inner_table.reference=outer_table.reference
-- If applying any ordering.
ORDER BY inner_events.ordering_row ASC
LIMIT 1
) AS subquery
where
-- Check if the rest of the EXISTS condition here.
your_condition=subquery.condition_row
);