Использование 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'"
}
]
}
]
}
}