![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Обычно указатель SQL ссылается на колонки таблицы.
Но индекс может также быть сформирован в выражениях,
включающих столбцы таблицы. Как пример, рассмотрите следующую таблицу, которая
отслеживает изменения суммы в долларах на различных счетах: Каждый вход в таблице account_change
делает запись депозита или отказа на счет. У депозитов есть положительное
"amt" и у отказов есть отрицательное "amt". Индекс acctchng_magnitude по номеру счета ("acct_no") и
на абсолютном значении суммы. Этот индекс позволяет делать эффективные
запросы по величине изменения счета.
Например, чтобы перечислить все изменения номера счета $xyz, которые
составляют больше 100.00$, можно сказать: Или, чтобы перечислить все изменения одного конкретного счета ($xyz) в
порядке уменьшающейся величины, можно написать: Оба вышеупомянутых запроса в качестве примера хорошо работали бы без
индекса acctchng_magnitude. Индекс acctchng_magnitude
просто помогает работать быстрее, особенно на базах данных, где есть много
записей в таблице для каждого счета. Используйте CREATE INDEX,
чтобы создать новый индекс по одному или более выражениям точно так же, как
создаете индекс на колонках. Единственная разница в том, что выражения
перечисляются как элементы, которые будут внесены в указатель, а
не имена столбцов. Планировщик запросов SQLite рассмотрит использование индекса по выражению,
когда выражение, которое внесено в указатель, появится в операторе Where или
в пункте ORDER BY запроса ТОЧНО как это написано в CREATE INDEX.
Планировщик вопроса не делает алгебры. Чтобы соответствовать ограничениям
оператора Where и условиям ORDER BY к индексам, SQLite требует, чтобы
выражения были теми же самыми, за исключением незначительных синтаксических
различий, таких как изменения пробела. Таким образом, если вы имеете: И затем вы управляете запросом: Тогда индекс не будет использоваться, потому что выражение в
CREATE INDEX (x+y) не является тем же самым выражением, как это появляется в
запросе (y+x). Эти два выражения могли бы быть математически эквивалентными,
но планировщик запросов SQLite настаивает, что они должны быть тем же самым,
не просто эквивалентными. Рассмотрите переписывание запроса таким образом: Этот второй запрос будет, вероятно, использовать индекс, потому что теперь
выражение в операторе Where (x+y) точно соответствует выражению в индексе. Есть определенные разумные ограничения на выражения, которые
появляются в CREATE INDEX: Выражения в CREATE INDEX могут обратиться только к колонкам
внесенной в указатель таблицы, но не к колонкам в других таблицах. Выражения в CREATE INDEX могут содержать вызовы функции, но только
функций, вывод которых всегда определяется полностью ее входными параметрами
(детерминированные функции).
Очевидно, такие функции как random(),
не будут работать хорошо в индексе. Но также и такие функции, как
sqlite_version(),
хотя они постоянные через любое соединение с базой данных, но они не
постоянные через жизнь всю основного файла базы данных, а следовательно не
могут использоваться в CREATE INDEX. Обратите внимание на то, что
определенные применением функции SQL по умолчанию считают
недетерминированными и их нельзя использовать в CREATE INDEX, если флаг
SQLITE_DETERMINISTIC не используется,
когда функция зарегистрирована. Выражения в CREATE INDEX не могут использовать подзапросы. Выражения могут использоваться только в CREATE INDEX, но не в
UNIQUE или ограничениях
PRIMARY KEY
в CREATE TABLE. Способность внести выражения в указатель была добавлена к SQLite с
version 3.9.0 (2015-10-14).
База данных, которая использует индекс по выражениям, не будет
применима более ранними версиями SQLite.
Choose any three.
CREATE TABLE account_change(chng_id INTEGER PRIMARY KEY,
acct_no INTEGER REFERENCES account,
location INTEGER REFERENCES locations,
amt INTEGER, -- in cents
authority TEXT, comment TEXT);
CREATE INDEX acctchng_magnitude ON account_change(acct_no, abs(amt));
SELECT * FROM account_change WHERE acct_no=$xyz AND abs(amt)>=10000;
SELECT * FROM account_change WHERE acct_no=$xyz ORDER BY abs(amt) DESC;
1.
Как использовать индексы по выражениям
CREATE TABLE t2(x,y,z);
CREATE INDEX t2xy ON t2(x+y);
SELECT * FROM t2 WHERE y+x=22;
SELECT * FROM t2 WHERE x+y=22;
2. Ограничения
3. Совместимость