Spec-Zone.ru › SQLite

Информация об индексировании виртуальных таблиц

struct sqlite3_index_info {
  /* Inputs */
  int nConstraint;           /* Number of entries in aConstraint */
  struct sqlite3_index_constraint {
     int iColumn;              /* Column constrained.  -1 for ROWID */
     unsigned char op;         /* Constraint operator */
     unsigned char usable;     /* True if this constraint is usable */
     int iTermOffset;          /* Used internally - xBestIndex should ignore */
  } *aConstraint;            /* Table of WHERE clause constraints */
  int nOrderBy;              /* Number of terms in the ORDER BY clause */
  struct sqlite3_index_orderby {
     int iColumn;              /* Column number */
     unsigned char desc;       /* True for DESC.  False for ASC. */
  } *aOrderBy;               /* The ORDER BY clause */
  /* Outputs */
  struct sqlite3_index_constraint_usage {
    int argvIndex;           /* if >0, constraint is part of argv to xFilter */
    unsigned char omit;      /* Do not code a test for this constraint */
  } *aConstraintUsage;
  int idxNum;                /* Number used to identify the index */
  char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  int orderByConsumed;       /* True if output is already ordered */
  double estimatedCost;           /* Estimated cost of using this index */
  /* Fields below are only available in SQLite 3.8.2 and later */
  sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
  /* Fields below are only available in SQLite 3.9.0 and later */
  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
  /* Fields below are only available in SQLite 3.10.0 and later */
  sqlite3_uint64 colUsed;    /* Input: Mask of columns used by statement */
};

Структура sqlite3_index_info и её подструктуры используются как часть интерфейса виртуальных таблиц для передачи информации и получения ответа от метода xBestIndex модуля виртуальной таблицы. Поля в разделе **Вводные данные** являются входными данными для xBestIndex и являются только для чтения. xBestIndex вставляет свои результаты в поля **Выходные данные**.

Массив aConstraint[] записывает ограничения условия WHERE в формате:

столбец ОП выражение

где ОП — это =, <, <=, > или >=. Конкретный оператор хранится в aConstraint[].op с использованием одного из значений SQLITE_INDEX_CONSTRAINT. Индекс столбца хранится в aConstraint[].iColumn. aConstraint[].usable имеет значение ИСТИНА, если выражение в правой части может быть вычислено (и, следовательно, ограничение применимо), и ЛОЖЬ, если нет.

Оптимизатор автоматически инвертирует члены вида «выражение ОП столбец» и выполняет другие упрощения условия WHERE, пытаясь получить как можно больше членов условия WHERE в указанном выше формате. Массив aConstraint[] сообщает только о членах условия WHERE, относящихся к конкретной виртуальной таблице, к которой обращаются.

Информация об операторе ORDER BY хранится в aOrderBy[]. Каждый член aOrderBy записывает столбец из оператора ORDER BY.

Поле colUsed указывает, какие столбцы виртуальной таблицы могут потребоваться для текущего сканирования. Столбцы виртуальной таблицы нумеруются с нуля в порядке, в котором они появляются в операторе CREATE TABLE, переданном в sqlite3_declare_vtab(). Для первых 63 столбцов (столбцы 0-62) соответствующий бит устанавливается в маске colUsed, если столбец может потребоваться SQLite. Если таблица имеет не менее 64 столбцов и какой-либо столбец справа от первых 63 столбцов требуется, то также устанавливается бит 63 colUsed. Другими словами, столбец iCol может потребоваться, если выражение (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) оценивается как ненулевое.

Метод xBestIndex должен заполнить aConstraintUsage[] информацией о том, какие параметры передать в xFilter. Если argvIndex>0, правая часть соответствующего aConstraint[] вычисляется и становится argvIndex-м элементом в argv. Если aConstraintUsage[].omit имеет значение ИСТИНА, то предполагается, что ограничение полностью обрабатывается виртуальной таблицей и, возможно, не будет проверяться кодом байт-кода повторно. Флаг aConstraintUsage[].omit — это подсказка по оптимизации. Когда флаг omit оставлен в своём значении по умолчанию — ЛОЖЬ, ограничение всегда будет проверяться отдельно в коде байт-кода. Если флаг omit изменён на ИСТИНА, то ограничение может или не может проверяться в коде байт-кода. Другими словами, когда флаг omit имеет значение ИСТИНА, нет гарантии, что ограничение не будет проверяться повторно с использованием байт-кода.

Значения idxNum и idxStr записываются и передаются в метод xFilter. sqlite3_free() используется для освобождения idxStr только в том случае, если needToFreeIdxStr имеет значение ИСТИНА.

orderByConsumed означает, что вывод от xFilter/xNext будет происходить в правильном порядке для удовлетворения условия ORDER BY, так что дополнительный шаг сортировки не требуется.

Значение estimatedCost — это оценка стоимости конкретной стратегии. Стоимость N указывает, что стоимость стратегии аналогична линейному сканированию таблицы SQLite с N строками. Стоимость log(N) указывает, что стоимость операции аналогична двоичному поиску по уникальному индексированному полю таблицы SQLite с N строками.

Значение estimatedRows — это оценка количества строк, которые будут возвращены стратегией.

Метод xBestIndex может дополнительно заполнить поле idxFlags маской флагов SQLITE_INDEX_SCAN_*. Одним из таких флагов является SQLITE_INDEX_SCAN_HEX, который, если установлен, заставляет вывод EXPLAIN QUERY PLAN отображать idxNum в шестнадцатеричном формате вместо десятичного. Другим флагом является SQLITE_INDEX_SCAN_UNIQUE, который, если установлен, указывает, что план запроса вернёт не более одной строки.

Кроме того, если xBestIndex установит флаг SQLITE_INDEX_SCAN_UNIQUE, то SQLite также предположит, что если вызов метода xUpdate() выполняется в рамках одного оператора для удаления или обновления строки виртуальной таблицы, и реализация возвращает SQLITE_CONSTRAINT, то нет необходимости отменять любые изменения в базе данных. Другими словами, если xUpdate() возвращает SQLITE_CONSTRAINT, содержимое базы данных должно быть точно таким же, как и до вызова xUpdate(). Напротив, если SQLITE_INDEX_SCAN_UNIQUE не установлен, а xUpdate возвращает SQLITE_CONSTRAINT, SQLite автоматически отменяет все изменения в базе данных, внесённые методом xUpdate.

ВАЖНО: Поле estimatedRows было добавлено в структуру sqlite3_index_info для SQLite версии 3.8.2 (2013-12-06). Если расширение виртуальной таблицы используется с версией SQLite, предшествующей 3.8.2, результаты попытки чтения или записи поля estimatedRows не определены (но, вероятно, включают сбой приложения). Поэтому поле estimatedRows следует использовать только в том случае, если sqlite3_libversion_number() возвращает значение, большее или равное 3008002. Аналогично, поле idxFlags было добавлено для версии 3.9.0 (2015-10-14). Поэтому оно может использоваться только в том случае, если sqlite3_libversion_number() возвращает значение, большее или равное 3009000.

3 метода, использующие этот объект: sqlite3_vtab_collation(), sqlite3_vtab_distinct(), sqlite3_vtab_rhs_value()

См. также списки Объектов, Констант и Функций.

SQLite is in the Public Domain.
https://sqlite.org/c3ref/index_info.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API