Мультизапросы, или пакетные запросы, позволяют отправлять несколько поисковых запросов в Manticore в рамках одного сетевого запроса.
👍 Зачем использовать мультизапросы?
Основная причина — производительность. Отправляя запросы в Manticore пакетом, а не по одному, вы экономите время за счет сокращения сетевых обходов. Кроме того, отправка запросов пакетом позволяет Manticore выполнять определенные внутренние оптимизации. Если оптимизации пакета неприменимы, запросы будут обрабатываться по отдельности.
⛔ Когда не следует использовать мультизапросы?
Мультизапросы требуют, чтобы все поисковые запросы в пакете были независимыми, что не всегда так. Иногда запрос B зависит от результатов запроса A, то есть запрос B можно настроить только после выполнения запроса A. Например, вы можете захотеть отобразить результаты из вторичного индекса только в том случае, если в основной таблице не найдено результатов, или вы можете указать смещение во втором наборе результатов на основе количества совпадений в первом наборе результатов. В этих случаях вам потребуется использовать отдельные запросы (или отдельные пакеты).
При использовании библиотек-коннекторов, таких как mysqli в PHP, вы можете добавить несколько запросов, а затем выполнить их все как единый пакет. Это будет работать как один пакет мультизапросов.
Примечание: Если вы используете консольный клиент MySQL, по умолчанию он интерпретирует точку с запятой (;) как разделитель и отправляет каждый запрос на сервер по отдельности; это не пакет мультизапросов. Чтобы переопределить это поведение, переопределите разделитель на стороне клиента на другой символ с помощью внутренней команды delimiter. После внесения этого изменения клиент будет отправлять всю строку с точками с запятой без изменений, что позволит работать "магии мультизапросов".
Такое побочное поведение консольного клиента часто может сбивать с толку, потому что вы можете заметить, что одна и та же последовательность команд ведет себя по-разному в консоли клиента MySQL по сравнению с другим протоколом, таким как SQL-over-HTTP. Это именно потому, что сам консольный клиент MySQL разделяет запросы с помощью точек с запятой, но другие протоколы могут отправлять всю последовательность как единый пакет.
Вы можете выполнить несколько поисковых запросов с помощью SQL, разделив их точкой с запятой. Когда Manticore получает запрос в таком формате от клиента, будут применены все оптимизации между операторами.
Мультизапросы не поддерживают запросы с FACET. Количество мультизапросов в одном пакете не должно превышать max_batch_queries.
- SQL
SELECT id, price FROM products WHERE MATCH('remove hair') ORDER BY price DESC; SELECT id, price FROM products WHERE MATCH('remove hair') ORDER BY price ASCИз консольного клиента MySQL/MariaDB:
DELIMITER _
SELECT id, price FROM products WHERE MATCH('remove hair') ORDER BY price DESC; SELECT id, price FROM products WHERE MATCH('remove hair') ORDER BY price ASC_
Существует две основные оптимизации, о которых следует знать: оптимизация общих запросов и оптимизация общих поддеревьев.
Оптимизация общих запросов означает, что searchd определит все те запросы в пакете, где различаются только настройки сортировки и группировки, и выполнит поиск только один раз. Например, если пакет состоит из 3 запросов, все они для "ipod nano", но 1-й запрос запрашивает топ-10 результатов, отсортированных по цене, 2-й запрос группирует по ID поставщика и запрашивает топ-5 поставщиков, отсортированных по рейтингу, а 3-й запрос запрашивает максимальную цену, полнотекстовый поиск по "ipod nano" будет выполнен только один раз, и его результаты будут повторно использованы для построения 3 различных наборов результатов.
Фасетный поиск — это особенно важный случай, который выигрывает от этой оптимизации. Действительно, фасетный поиск может быть реализован путем выполнения нескольких запросов: один для получения самих результатов поиска, и несколько других с тем же полнотекстовым запросом, но с разными настройками группировки для получения всех требуемых групп результатов (топ-3 автора, топ-5 поставщиков и т.д.). Пока полнотекстовый запрос и настройки фильтрации остаются неизменными, сработает оптимизация общих запросов и значительно повысит производительность.
Оптимизация общих поддеревьев еще интереснее. Она позволяет searchd использовать сходства между пакетными полнотекстовыми запросами. Она определяет общие части полнотекстовых запросов (поддеревья) во всех запросах и кэширует их между запросами. Например, рассмотрим следующий пакет запросов:
donald trump president
donald trump barack obama john mccain
donald trump speech
Есть общая часть из двух слов donald trump, которую можно вычислить только один раз, затем закэшировать и использовать во всех запросах. И оптимизация общих поддеревьев делает именно это. Размер кэша на запрос строго контролируется директивами subtree_docs_cache и subtree_hits_cache (чтобы кэширование всех шестнадцати газиллионов документов, соответствующих "i am", не исчерпало оперативную память и мгновенно не убило ваш сервер).
Как можно определить, были ли запросы в пакете фактически оптимизированы? Если да, то соответствующий журнал запросов будет содержать поле "multiplier", указывающее, сколько запросов было обработано вместе:
Обратите внимание на поле "x3". Оно означает, что этот запрос был оптимизирован и обработан в подпакете из 3 запросов.
- log
[Sun Jul 12 15:18:17.000 2009] 0.040 sec x3 [ext/0/rel 747541 (0,20)] [lj] the
[Sun Jul 12 15:18:17.000 2009] 0.040 sec x3 [ext/0/ext 747541 (0,20)] [lj] the
[Sun Jul 12 15:18:17.000 2009] 0.040 sec x3 [ext/0/ext 747541 (0,20)] [lj] theДля справки, вот как выглядел бы обычный журнал, если бы запросы не были пакетными:
- log
[Sun Jul 12 15:18:17.062 2009] 0.059 sec [ext/0/rel 747541 (0,20)] [lj] the
[Sun Jul 12 15:18:17.156 2009] 0.091 sec [ext/0/ext 747541 (0,20)] [lj] the
[Sun Jul 12 15:18:17.250 2009] 0.092 sec [ext/0/ext 747541 (0,20)] [lj] theОбратите внимание, как время на запрос в случае мультизапроса улучшилось в 1,5–2,3 раза в зависимости от конкретного режима сортировки.
Мультизапросы в основном поддерживаются для пакетной обработки запросов и получения метаинформации после таких пакетов. Из-за этого ограничения в пакетах разрешено только небольшое подмножество операторов. В одном пакете можно комбинировать только операторы SELECT, SHOW и SET.
Вы можете использовать SELECT как обычно; однако обратите внимание, что все запросы будут выполняться вместе за один проход. Если запросы не связаны, нет пользы от мультизапросов. Демон обнаружит это и запустит запросы по одному.
Вы можете использовать SHOW для обработки предупреждений, статуса, статуса агента, метаданных, профиля и плана. Все остальные операторы SHOW в пакетах будут тихо игнорироваться без вывода. Например, вы не можете выполнить SHOW TABLES, SHOW THREADS или SHOW VARIABLES, или любой другой оператор, не упомянутый выше, при пакетной обработке.
Вы можете использовать SET только для SET PROFILING. Все остальные команды SET ... будут тихо игнорироваться.
Порядок выполнения также отличается. Демон обрабатывает пакеты в два прохода.
Сначала он собирает все операторы SELECT и выполняет все встреченные операторы SET PROFILING одновременно. Как побочный эффект, только последний оператор SET PROFILING является эффективным. Если вы выполните мультизапрос, например: SET PROFILING=1; SELECT...; SHOW META; SHOW PROFILE; SET PROFILING=0, вы не увидите никакого профиля, потому что на первом проходе демон выполняет SET PROFILING=1, а затем сразу SET PROFILING=0.
Во-вторых, демон пытается выполнить один пакетный запрос со всеми собранными операторами SELECT. Если операторы не связаны, он выполнит их один за другим.
Наконец, он проходит по исходной последовательности пакета и возвращает данные подрезультата и метаданные из набора результатов для каждого SELECT и SHOW. Поскольку все операторы SET PROFILING были выполнены на первом проходе, они пропускаются на этом втором проходе.
each SELECT and SHOW. Since all SET PROFILING statements were executed in the first pass, they are skipped on this second pass.