Подтвердить что ты не робот

Поддерживает ли многоколоночный индекс для выбора одного столбца?

У меня есть (например) индекс:

CREATE INDEX someIndex ON orders (customer, date);

Этот индекс только ускоряет запросы, в которых используются клиент и дата, или ускоряет запросы для одного столбца, подобного этому?

SELECT * FROM orders WHERE customer > 33;

Я использую SQLite.


Если да, то почему можно создать более одного индекса для таблицы?


Еще один вопрос: насколько быстрее комбинированный индекс по сравнению с двумя индексами разделителя при использовании обоих столбцов в запросе?

4b9b3361

Ответ 1

marc_s имеет правильный ответ на ваш первый вопрос. Первый ключ в индексе с несколькими ключами может работать как один индекс ключа, но любые последующие ключи не будут.

Что касается того, насколько быстрее составной индекс зависит от ваших данных и как вы структурируете свой индекс и запрос, но это обычно важно. Индексы по существу позволяют Sqlite выполнять двоичный поиск в полях.

Используя пример, который вы указали, если вы запустили запрос:

SELECT * from orders where customer > 33 && date > 99

Sqlite сначала получит все результаты, используя двоичный поиск во всей таблице, где клиент > 33. Затем он выполнит двоичный поиск только для тех результатов, которые ищут дату > 99.

Если вы сделали тот же запрос с двумя отдельными индексами для клиента и даты, Sqlite должен был бы двоично искать всю таблицу дважды, сначала для клиента и снова для даты.

Итак, сколько из увеличения скорости вы увидите, зависит от того, как вы структурируете свой индекс по вашему запросу. В идеале первое поле в вашем индексе и ваш запрос должны быть теми, которые устраняют наиболее возможные совпадения, поскольку это даст наибольшее увеличение скорости за счет значительного сокращения объема работы, которую должен выполнить второй поиск.

Для получения дополнительной информации см. это: http://www.sqlite.org/optoverview.html

Ответ 2

Я уверен, что это сработает, да - в MS SQL Server все равно.

Однако этот индекс не поможет вам, если вам нужно выбрать только дату, например. диапазон дат. В этом случае вам может понадобиться создать второй индекс только для даты, чтобы сделать эти запросы более эффективными.

Марк

Ответ 3

Я обычно использую комбинированные индексы для сортировки данных, которые я хочу разбивать на страницы или запрашивать "по крупицам".

Предполагая, что клиент может сделать более одного заказа.. и существуют клиенты с 0 по 11, и есть несколько заказов на каждого клиента, которые вставлены в случайном порядке. Я хочу сортировать запрос на основе номера клиента, за которым следует дата. Вы должны отсортировать поле id, а также последнее, чтобы разбить наборы, где у клиента есть несколько идентичных дат (даже если это может никогда не произойти).

sqlite> CREATE INDEX customer_asc_date_asc_index_asc ON orders
          (customer ASC, date ASC, id ASC);

Получить страницу 1 из отсортированного запроса (ограниченным до 10 элементов):

sqlite> SELECT id, customer, date FROM orders
          ORDER BY customer ASC, date ASC, id ASC LIMIT 10;

2653|1|1303828585
2520|1|1303828713
2583|1|1303829785
1828|1|1303830446
1756|1|1303830540
1761|1|1303831506
2442|1|1303831705
2523|1|1303833761
2160|1|1303835195
2645|1|1303837524

Получить следующую страницу:

sqlite> SELECT id, customer, date FROM orders WHERE
          (customer = 1 AND date = 1303837524 and id > 2645) OR
          (customer = 1 AND date > 1303837524) OR
          (customer > 1)
          ORDER BY customer ASC, date ASC, id ASC LIMIT 10;

2515|1|1303837914
2370|1|1303839573
1898|1|1303840317
1546|1|1303842312
1889|1|1303843243
2439|1|1303843699
2167|1|1303849376
1544|1|1303850494
2247|1|1303850869
2108|1|1303853285

И так далее...

Наличие индексов на месте уменьшает сканирование индекса на стороне сервера, если вы в противном случае использовали бы запрос OFFSET в сочетании с LIMIT. Время запроса увеличивается, и жесткие диски требуют более высокой скорости смещения. Использование этого метода устраняет это.

Использование этого метода рекомендуется, если вы планируете позднее присоединять данные, но для этого требуется только ограниченный набор данных. Присоединитесь к SUBSELECT, как описано выше, чтобы уменьшить накладные расходы памяти для больших таблиц.