Использование EXPLAIN в Reindexer

EXPLAIN в Reindexer используется для анализа процесса выполнения запросов и определения среди них требующих оптимизации. Применять эту функцию можно совместно с операторами SELECT, UPDATE и DELETE.

Для использования функции укажите ключевое слово EXPLAIN перед SQL-запросом или добавьте в тело запроса "explain": true при использовании DSL, и план выполнения запроса будет возвращен с результатами.

Функция EXPLAIN возвращает объект, включающий следующую информацию о процессе выполнения запроса:

Параметр Описание Тип данных Возможные значения Примечание
total_us Общее время выполнения запроса int - -
preselect_us Время на подготовку JOIN-подзапросов (по большей части состоит из времени предварительной выборки из joined-неймспейсов) int - -
prepare_us Время подготовки и оптимизации запроса int - -
indexes_us Время выборки ключей из индексов int - -
postprocess_us Время подготовки итераторов и обработки LEFT JOIN int - -
loop_us Время работы цикла пересечения выборок по отдельным условиям int - -
general_sort_us Время выполнения сортировки результатов запроса int - -
sort_index Индекс, использующийся для сортировки результатов string - -
sort_by_uncommitted_index Признак завершения фоновой оптимизации индексов bool true,
false
-
selectors Селекторы фильтров, используемые для обработки условий запроса array - -
items Количество просканированных элементов (строк неймспейса, записей) int - Поле элемента массива selectors.
Возвращается при значении поля method = scan
field Имя поля или индекс, использующийся для обработки условия запроса string - Поле элемента массива selectors.
Возвращается при значении поля method = index или при method = scan(для этого случая field = -scan)
comparators Количество компараторов, используемых для данного селектора int - Поле элемента массива selectors
Возвращается при значении поля type = OnlyComparator
matched Количество обработанных элементов удовлетворивших компаратор или соответствующих данному селектору int - Поле элемента массива selectors
cost Ожидаемые затраты (количество итераций) на использование этого селектора int - Поле элемента массива selectors
Позволяет оценить время, которое проходит, прежде чем начнётся этап вывода данных
method Метод, используемый для обработки условия string scan — Полное сканирование.
index — Выборка из индекса.
preselected_values — Для присоединяемого неймспейса был выполнен относящийся к нему подзапрос и получены значения строк, удовлетворяющие ему. После этого была снята блокировка мьютекса с присоединяемого неймспейса и, при выполнении основного запроса, была выполнена дофильтровка по условию ON только среди выбранных на предыдущем этапе строк.
preselected_rows — Для присоединяемого неймспейса был выполнен относящийся к нему подзапрос и получены id строк, удовлетворяющие ему. После, при выполнении основного запроса, дофильтровка по условию ON выполнялась только среди этих строк.
no_preselect — Предварительная выборка из присоединяемого неймспейса не производилась
Поле элемента массива selectors
type Тип итератора (способ итерирования по выборке) string SingleRange — Итерирование по индексу в прямом порядке.
RevSingleRange — Итерирование по индексу в обратном порядке.
OnlyComparator — Выборка по индексу не проводилась, а для каждого значения выполнялась проверка условия.
Forward — Выборка в прямом направлении по нескольким id сетам, полученным от индекса.
Reverse — Выборка в обратном направлении по нескольким id сетам, полученным от индекса.
SingleIdset — Выборка в прямом направлении по единственному id сету, полученному от индекса.
RevSingleIdset — Выборка в обратном направлении по единственному id сету, полученному от индекса.
SingleIdSetWithDeferedSort — id сеты были объединены в один, по которому и происходила выборка.
RevSingleIdSetWithDeferedSort — id сеты были объединены в один, по которому и происходила выборка в обратном порядке.
Unsorted — Несортированная выборка.
UnbuiltSortOrdersIndex — Итерирование по b-tree индексу (если не произведена его оптимизация)
Поле элемента массива selectors
field_type Тип поля из запроса string non-indexed,
indexed
Поле элемента массива selectors
explain_select Explain одного из выполнений вложенного запроса к присоединяемому неймспейсу object - Поля объекта аналогичны описанным выше
explain_preselect Explain для предварительной выборки для вложенного запроса к присоединяемому неймспейсу object - Возвращается при значении поля method = preselected_rows или method = preselected_values.
Поля объекта аналогичны описанным выше
on_conditions_injections Информация о подстановке условий из ON() в основной запрос object -
namespace Имя присоединяемого неймспейса string - Поле объекта on_conditions_injections
on_condition Условие присоединения. SQL-подобная строка string - Поле объекта on_conditions_injections
type Источник значений string by_value — предварительная выборка значений,
select — дополнительная выборка
Поле объекта on_conditions_injections
total_time_us Общее время, затраченное на попытку подстановки условия int - Поле объекта on_conditions_injections
success Признак успешного выполнения подстановки boolean - Поле объекта on_conditions_injections
injected_condition Условие, подставленное в основной запрос, в результате оптимизации. SQL-подобная строка string - Поле объекта on_conditions_injections
conditions Информация о процессе обработки отдельных условий JOIN array - Поле объекта on_conditions_injections.
Каждый элемент массива содержит объект explain_select (описан выше), а также несколько дополнительных полей: condition, total_time_us, success, agg_type, values_count, new_condition
condition Условие JOIN (из on_condition). SQL-подобная строка string - Поле элемента массива conditions
total_time_us Общее время, затраченное на подстановку (от начала попытки выполнения присоединения до его успешного окончания или отказа) int - Поле элемента массива conditions
success Признак успешного выполнения подстановки boolean - Поле элемента массива conditions
agg_type Тип агрегации, использованный для подстановки string min — получить минимальное значение в столбце,
max — получить минимальное значение в столбце,
distinct — получить записи с уникальными значениями
Поле элемента массива conditions
values_count Результирующий размер выборки значений по запросу, который был использован для выборки из joined-неймспейса int Поле элемента массива conditions
new_condition Подставленное в основной запрос условие. SQL-подобная строка string Поле элемента массива conditions

Примеры запроса с EXPLAIN и ответа:

curl --location --request POST 'http://172.0.0.1:9088/api/v1/db/frontapi/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "media_items",
  "type": "select",
  "filters": [
    {
      "field": "year",
      "cond": "GE",
      "value": [
        2000
      ],
      "join_query": {
        "namespace": "favorites",
        "type": "INNER",
        "on": [
          {
            "left_field": "id",
            "right_field": "content_id",
            "cond": "EQ"
          }
        ]
      }
    }
  ],
  "select_filter": [
    "name"
  ],
  "explain": true
}'
{
  "items": [
    {
      "name": "New",
      "joined_favorites": [
        {
          "id": 0,
          "content_id": 0
        }
      ]
    }
  ],
  "namespaces": [
    "media_items",
    "favorites"
  ],
  "cache_enabled": false,
  "explain": {
    "total_us": 429,
    "preselect_us": 18,
    "prepare_us": 166,
    "indexes_us": 17,
    "postprocess_us": 114,
    "loop_us": 111,
    "general_sort_us": 0,
    "sort_index": "-",
    "sort_by_uncommitted_index": false,
    "selectors": [
      {
        "keys": 1,
        "comparators": 0,
        "cost": 1,
        "field": "id",
        "field_type": "indexed",
        "matched": 1,
        "method": "index",
        "type": "SingleIdset"
      },
      {
        "field": "inner_join favorites",
        "matched": 1,
        "selects_count": 1,
        "join_select_total": 88,
        "method": "no_preselect",
        "keys": 0,
        "explain_select": {
          "total_us": 57,
          "preselect_us": 0,
          "prepare_us": 11,
          "indexes_us": 12,
          "postprocess_us": 21,
          "loop_us": 11,
          "general_sort_us": 0,
          "sort_index": "-",
          "sort_by_uncommitted_index": false,
          "selectors": [
            {
              "keys": 1,
              "comparators": 0,
              "cost": 1,
              "field": "content_id",
              "field_type": "indexed",
              "matched": 1,
              "method": "index",
              "type": "SingleIdset"
            }
          ]
        }
      }
    ],
    "on_conditions_injections": [
      {
        "namespace": "favorites",
        "on_condition": "INNER JOIN ON (favorites.content_id = id)",
        "type": "select",
        "total_time_us": 138,
        "success": true,
        "injected_condition": "(id = '0' )",
        "conditions": [
          {
            "condition": "favorites.content_id = id",
            "total_time_us": 112,
            "success": true,
            "explain_select": {
              "total_us": 63,
              "preselect_us": 0,
              "prepare_us": 9,
              "indexes_us": 19,
              "postprocess_us": 20,
              "loop_us": 13,
              "general_sort_us": 0,
              "sort_index": "-",
              "sort_by_uncommitted_index": false,
              "selectors": [
                {
                  "keys": 1,
                  "comparators": 0,
                  "cost": 1,
                  "field": "content_id",
                  "field_type": "indexed",
                  "matched": 1,
                  "method": "index",
                  "type": "SingleIdset"
                }
              ]
            },
            "agg_type": "distinct",
            "values_count": 1,
            "new_condition": "id = '0'"
          }
        ]
      }
    ]
  }
}