SQL Server 2008: Упорядочивание датой и временем является слишком медленным

Я думаю, что повторяю другие комментарии здесь, что инструкции по MS, уже связанные, являются превосходной начальной точкой. Я моделирую свой код в основном тех.

, Который интересен, потому что мой менеджер сказал мне в прошлом, что он не слишком увлечен ими: D

у Вас есть забавная задача перед Вами мой друг. Всего наилучшего, и спросите, нужно ли Вам что-нибудь больше:)

23
задан silent 11 November 2009 в 17:38
поделиться

7 ответов

Сортировка по id , вероятно, использует сканирование кластерного индекса, тогда как упорядочение по datetime использует либо сортировку, либо поиск по индексу.

] Оба этих метода медленнее, чем сканирование кластерного индекса.

Если ваша таблица кластеризована по id , в основном это означает, что она уже отсортирована. Записи содержатся в B + Tree , который имеет связанный список, связывающий страницы в порядке id . Механизм должен просто пройти по связанному списку, чтобы получить записи, упорядоченные по id .

Если id были вставлены в последовательном порядке, это означает, что физический порядок строк будет соответствовать логическому порядку, и сканирование кластерного индекса будет еще быстрее.

Если вы хотите, чтобы ваши записи были упорядочены по datetime , есть два варианта:

  • Возьмите все записи из таблицы и отсортируйте их. Медлительность очевидна.
  • Используйте индекс на datetime . Индекс хранится в отдельном пространстве диска, это означает, что движку необходимо перемещаться между страницами индекса и страницами таблицы во вложенном цикле. Он также работает медленнее.

Чтобы улучшить порядок, вы можете создать отдельный покрывающий индекс на datetime :

CREATE INDEX ix_mytable_datetime ON mytable (datetime) INCLUDE (field1, field2, …)

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

Этот индекс похож на теневую копию вашей таблицы, но с данными, отсортированными в другом порядке.

Это позволит избавиться от поиска по ключевым словам (поскольку индекс содержит все данные), которые будут упорядочивать по datetime так же быстро, как на id .

Обновление:

Новое сообщение в блоге по этой проблеме:

25
ответ дан 29 November 2019 в 02:25
поделиться

Добавьте дату и время в новый индекс, добавление его к идентификатору все равно не поможет.

2
ответ дан 29 November 2019 в 02:25
поделиться

Для соблюдения ORDER BY у движка есть две альтернативы:

  • сканировать строки, используя индекс, который предлагает запрошенный порядок
  • сортировать строки

Первый вариант быстрый, второй медленный. Проблема в том, что для использования индекс должен быть покрывающим индексом . Это означает, что он содержит все столбцы в списке проекции SELECT и все столбцы, используемые в предложениях WHERE (как минимум). Если индекс не покрывает, то движку придется искать кластерный индекс (т.е. «таблицу») для каждой строки, чтобы получить значения необходимых столбцов. Этот постоянный поиск значений стоит дорого, и есть переломный момент, когда механизм (справедливо) решит, что более эффективно просто сканировать кластерный индекс и отсортировать результат, фактически игнорируя некластеризованный индекс. Подробности см. см. Ответы на запросы «Переломный момент» .

Рассмотрим следующие три запроса:

SELECT dateColumn FROM table ORDER BY dateColumn
SELECT * FROM table ORDER BY dateColumn
SELECT someColumn FROM table ORDER BY dateColumn

Первый будет использовать некластеризованный индекс для dateColumn. Но второй не будет использовать индекс для dateColumn, скорее всего, выберет сканирование и сортировку вместо 1M строк. С другой стороны, третий запрос может извлечь выгоду из индекса в Table (dateColumn) INCLUDE (someColumn) .

Эта тема подробно освещена в MSDN, см. Основы разработки индекса , Общие рекомендации по созданию индексов , Рекомендации по разработке некластеризованных индексов или Как: оптимизировать индексы SQL .

В конечном итоге, наиболее важным выбором дизайна вашей таблицы является кластерный индекс, который вы используете. Почти всегда первичный ключ (обычно автоматически увеличивающийся идентификатор) остается в качестве кластеризованного индекса, решение, которое приносит пользу только определенным нагрузкам OLTP.

И, наконец, довольно очевидный вопрос: зачем вам заказывать 1 миллион строк ?? Вы ведь не можете их отобразить? Более подробное описание вашего варианта использования может помочь нам найти для вас лучший ответ.

6
ответ дан 29 November 2019 в 02:25
поделиться

Может быть, есть индекс для вашего столбца int, но не для столбца datetime? Посмотрите на план выполнения.

1
ответ дан 29 November 2019 в 02:25
поделиться

Сортировка по id , вероятно, использует сканирование кластеризованного индекса, тогда как сортировка по datetime использует либо сортировку, либо поиск по индексу.

Оба эти метода больше медленнее, чем сканирование кластерного индекса.

Если ваша таблица кластеризована по идентификатору , в основном это означает, что она уже отсортирована. Записи содержатся в B + Tree , который имеет связанный список, связывающий страницы в порядке id . Механизм должен просто просмотреть связанный список, чтобы получить записи, упорядоченные по id .

Если id были вставлены в последовательном порядке, это означает, что физический порядок строк будет соответствовать логическому порядку, и сканирование кластерного индекса будет еще быстрее.

Если вы хотите, чтобы ваши записи были упорядочены по datetime , есть два варианта:

  • Взять все записи из таблицы и отсортировать их. Медлительность очевидна.
  • Используйте индекс на datetime . Индекс хранится в отдельном пространстве диска, это означает, что движку необходимо перемещаться между страницами индекса и страницами таблицы во вложенном цикле. Он также работает медленнее.

Чтобы улучшить порядок, вы можете создать отдельный индекс покрытия на datetime :

CREATE INDEX ix_mytable_datetime ON mytable (datetime) INCLUDE (field1, field2, …)

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

Этот индекс похож на теневую копию вашей таблицы, но с данными, отсортированными в другом порядке.

Это позволит избавиться от ключевых поисков (поскольку индекс содержит все данные), которые будут упорядочивать по datetime так же быстро, как и на id .

Обновление:

Свежая запись в блоге по этой проблеме:

0
ответ дан 29 November 2019 в 02:25
поделиться

Вы добавили поле DateTime в «индекс» или в эксклюзивный индекс? Вы фильтруете свой выбор по другому полю и DateTime или только по этому?

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

0
ответ дан 29 November 2019 в 02:25
поделиться

Если ваше поле datetime содержит много различных значений и эти значения редко меняются, определите кластеризованный индекс для поля datetime, это будет отсортировать фактические данные по значению datetime. См. http://msdn.microsoft.com/en-us/library/aa933131 (SQL.80) .aspx для использования кластерных индексов.

Это замедлит поиск int, поскольку они будет переведено на использование некластеризованного индекса.

0
ответ дан 29 November 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: