manual/russian/Searching/Sub-selects.md
Manticore поддерживает подзапросы SELECT в SQL следующем формате:
SELECT * FROM (SELECT ... ORDER BY cond1 LIMIT X) ORDER BY cond2 LIMIT Y
Внешний SELECT допускает только конструкции ORDER BY и LIMIT. В настоящее время подзапросы используются в двух случаях:
Когда у вас есть запрос с двумя функциями ранжирования UDF, одна очень быстрая, другая медленная, и выполняется полнотекстовый поиск с большим набором результатов совпадений. Без подвыборки запрос выглядел бы так:
SELECT id,slow_rank() as slow,fast_rank() as fast FROM index
WHERE MATCH(‘some common query terms’) ORDER BY fast DESC, slow DESC LIMIT 20
OPTION max_matches=1000;
С подвыборками запрос можно переписать следующим образом:
SELECT * FROM
(SELECT id,slow_rank() as slow,fast_rank() as fast FROM index WHERE
MATCH(‘some common query terms’)
ORDER BY fast DESC LIMIT 100 OPTION max_matches=1000)
ORDER BY slow DESC LIMIT 20;
В исходном запросе UDF slow_rank() вычисляется для всего набора результатов совпадений. С помощью подзапросов SELECT для всего набора совпадений вычисляется только fast_rank(), а slow_rank() вычисляется для ограниченного набора.
Второй случай полезен для больших наборов результатов, поступающих из распределённой таблицы.
Для этого запроса:
SELECT * FROM my_dist_index WHERE some_conditions LIMIT 50000;
Если у вас 20 узлов, каждый узел может отправить мастеру максимум 50K записей, что в сумме дает 20 x 50K = 1M записей. Однако, поскольку мастер возвращает только 50K (из 1M), может быть достаточно, чтобы узлы отправляли только топ 10K записей. С подзапросом вы можете переписать запрос так:
SELECT * FROM
(SELECT * FROM my_dist_index WHERE some_conditions LIMIT 10000)
ORDER by some_attr LIMIT 50000;
В этом случае узлы получают только внутренний запрос и выполняют его. Это означает, что мастер получит только 20x10K=200K записей. Мастер возьмет все полученные записи, переупорядочит их по ВНЕШНЕМУ условию и вернет лучшие 50K записей. Подвыборка помогает сократить трафик между мастером и узлами, а также уменьшить время обработки мастера (так как он обрабатывает только 200K вместо 1M записей).