2012-06-26 5 views
2

В последнее время я столкнулся с шаблоном (не уверен, может быть анти-шаблоном) сортировки данных в запросе SELECT. Шаблон более подробный и не декларативный способ упорядочения данных. Шаблон состоит в том, чтобы выгрузить релевантные данные из фактической таблицы во временную таблицу, а затем применить orderby в поле во временной таблице. Полагаю, единственная причина, почему кто-то будет делать это, - это улучшить производительность (что я сомневаюсь) и никакой другой выгоды.Использование таблицы temp для сортировки данных в SQL Server

См., Например, Скажем, есть таблица пользователей. Таблица может содержать строки в миллионах. Мы хотим получить всех пользователей, чье имя начинается с «G» и сортируется по имени. Естественный и более декларативный способ реализации SQL запроса для этого сценария:

Более естественный и декларативный способ

SELECT * FROM Users 
WHERE NAME LIKE 'G%' 
ORDER BY Name 

Многословный путь

SELECT * INTO TempTable 
FROM Users 
WHERE NAME LIKE 'G%' 

SELECT * FROM TempTable 
ORDER BY Name 

С этой связи я есть несколько вопросов:

  1. Будет ли разница в производительности между двумя способами, если есть без индекса на поле имени. Если да, то какой будет лучше.

  2. Будет ли разница в производительности между двумя способами, если есть индекс на поле имени. Если да, то какой будет лучше.

  3. Не должен ли оптимизатор SQL Server создавать одинаковый план выполнения для обоих способов?

  4. Есть ли какая-либо польза в написании многословного пути от любых других перфективных, таких как блокировка/блокировка?

Заранее спасибо.

+0

Единственное преимущество, которое я вижу в этом случае, заключается в том, что мы хотим сортировать столбец, который не индексируется в родительской таблице. – Dimitri

+0

В контексте, где вы видели шаблон, вы проверили оба пути? Используется ли временная таблица в других вариантах? – Paparazzi

+0

@Blam: У меня не возникло твоего вопроса. Я не сравнивал производительность. Я только что видел вышеупомянутый оператор SQL (многословный путь), и вопрос пришел ко мне. Я не мог убедить себя, что это может помочь в улучшении производительности. –

ответ

1

Reguzlarly: Anti-образ людей без идеи, что они делают.

SOMETIMES: хорошо, потому что SQL Server имеет проблему, которая не разрешима в противном случае - не видно, что в ней есть.

Это замедляет работу, поскольку он заставляет таблицу tmpddb полностью заполняться FIRST, в противном случае запрос мог бы ВОЗМОЖНО быть более эффективным.

Последнее время я видел, что было, как 3 года назад. Мы получили его в 3 раза быстрее, не будучи умным и использования TempDb таблицы;)

Ответов:

1: Нет, он все еще нуждается сканирование таблицы, очевидно.

2: Возможно - зависит от объема данных, но индексный поиск по индексу будет содержать данные в порядке уже (по мере упорядочения индекса по содержанию).

3: no. Очевидно. Оптимизация плана запроса - заявление по инструкции. Сократив выполнение в 2, оптимизатор запросов НЕ МОЖЕТ объединить объединение в первый оператор.

4: Только если вы столкнулись с проблемой оптимизатора запросов или ограничением количества таблиц, к которым вы можете присоединиться, - не в этом вырожденном случае (вырожденном в техническом смысле, то есть очень упрощенном). BUt, если вам нужно присоединиться к МНОГИМ МНОГИМ таблицам, лучше идти с промежуточным шагом.

+0

+1. Короче говоря, использование таблицы temp для сортировки данных в таких упрощенных сценариях (один сценарий упоминается в примере) не улучшит производительность, а наоборот, может ухудшиться. Правильно? –

+0

Noot may, will. он должен материализовать данные в временную таблицу без учета порядка, а затем заказать - что убивает любой способ для оптимизатора запросов, чтобы увидеть, что порядок есть в выборе, и означает, что вы не можете возвращать данные. UNTIL вся таблица которые могут произойти иначе. Очень плохо. – TomTom

0

Невозможно использовать второй подход, о котором я могу думать.

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

В случае, если данные недоступны, предварительно упорядоченный SQL Server будет сортировать его в рабочей таблице либо в памяти, либо в tempdb в любом случае, и добавление явной таблицы #temp просто добавляет ненужный дополнительный шаг.

Редактировать

Я полагаю, один случай, когда второй подход может дать явное преимущество может быть, если наличие ORDER BY вызванного SQL Server, чтобы выбрать другой план, который оказался субоптимальным. В этом случае я бы разрешил это по-другому, либо улучшив статистику, либо используя рекомендации/запрос переписать, чтобы избежать нежелательного плана.

0

Если поле, в котором вы хотите сделать заказ, не индексируется, вы можете поместить все в таблицу temp и проиндексировать его, а затем выполнить заказ, и это может быть быстрее. Вы должны были бы проверить, чтобы убедиться.

+1

Разве данные не нужно сортировать для создания индекса? В таком случае зачем беспокоиться? Кажется, что добавляет дополнительные накладные расходы поверх обычной сортировки. –

Смежные вопросы