# Подвыборки

Manticore поддерживает подзапросы SELECT в SQL следующем формате:

```sql
SELECT * FROM (SELECT ... ORDER BY cond1 LIMIT X) ORDER BY cond2 LIMIT Y
```

Внешний SELECT допускает только конструкции `ORDER BY` и `LIMIT`. В настоящее время подзапросы используются в двух случаях:

1. Когда у вас есть запрос с двумя функциями ранжирования UDF, одна очень быстрая, другая медленная, и выполняется полнотекстовый поиск с большим набором результатов совпадений. Без подвыборки запрос выглядел бы так:

    ```sql
    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;
    ```

    С подвыборками запрос можно переписать следующим образом:

    ```sql
    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()` вычисляется для ограниченного набора.

2. Второй случай полезен для больших наборов результатов, поступающих из распределённой таблицы.

    Для этого запроса:

    ```sql
    SELECT * FROM my_dist_index WHERE some_conditions LIMIT 50000;
    ```

    Если у вас 20 узлов, каждый узел может отправить мастеру максимум 50K записей, что в сумме дает 20 x 50K = 1M записей. Однако, поскольку мастер возвращает только 50K (из 1M), может быть достаточно, чтобы узлы отправляли только топ 10K записей. С подзапросом вы можете переписать запрос так:

    ```sql
    SELECT * FROM
         (SELECT * FROM my_dist_index WHERE some_conditions LIMIT 10000)
     ORDER by some_attr LIMIT 50000;
    ```

    В этом случае узлы получают только внутренний запрос и выполняют его. Это означает, что мастер получит только 20x10K=200K записей. Мастер возьмет все полученные записи, переупорядочит их по ВНЕШНЕМУ условию и вернет лучшие 50K записей. Подвыборка помогает сократить трафик между мастером и узлами, а также уменьшить время обработки мастера (так как он обрабатывает только 200K вместо 1M записей).
<!-- proofread -->

