Можно ли добавить индекс во временную таблицу? И какая разница между созданием #t и объявлением @t - PullRequest
13 голосов
/ 17 июня 2011

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

Вывод представления можно упростить следующим образом:

PID (int), Kind (int), Date (date), D1,D2..DN

, где поля PID и Date и Kind не являются уникальными (может быть несколько строк, имеющих одинаковую комбинацию pid, kind, date), но это те, которые будут использоваться в соединении, как это

left join ComplexView mkcs on mkcs.PID=q4.PersonID and mkcs.Date=q4.date and mkcs.Kind=1
left join ComplexView mkcl on mkcl.PID=q4.PersonID and mkcl.Date=q4.date and mkcl.Kind=2
left join ComplexView mkco on mkco.PID=q4.PersonID and mkco.Date=q4.date and mkco.Kind=3

Теперь, если я просто сделаю это так, выполнение запроса займет значительное время, потому что я предполагаю, что сложное представление запускается три раза, и из его огромного количества строк фактически используются только некоторые (например, из 40000). используется только 2000)

Что я сделал, так это объявил @temptable и вставил в @temptable select * из ComplexView где Date ... - один раз для каждого запроса я выбираю только строки, которые собираюсь использовать, из моего ComplexView, а затем присоединяюсь к этому @temptable.

Это значительно сократило время выполнения.

Однако я заметил, что если я создаю таблицу в своей базе данных и добавляю кластеризованный индекс по PID, Kind, Date (неуникально кластеризованный) и беру данные из этой таблицы, то выполняю delete * из этой таблицы и Вставка в эту таблицу из комплексного представления занимает несколько секунд (3 или 4), а затем, используя эту таблицу в моем запросе (осталось три раза присоединиться к ней), уменьшите время запроса вдвое, с 1 минуты до 30 секунд!

Итак, мой вопрос, прежде всего, - возможно ли создавать индексы для объявленных @temptables. А потом - я видел, как люди говорили о синтаксисе "create #temptable". Может это то что мне нужно? Где я могу прочитать о том, в чем разница между объявлением @temptable и созданием #temptable? Что я буду использовать для такого запроса, как мой? (этот запрос предназначен для отчета MS Reporting Services, если он имеет значение).

Ответы [ 3 ]

5 голосов
/ 17 июня 2011

#tablename - это физическая таблица, хранящаяся в tempdb, которую сервер будет автоматически отбрасывать при закрытии соединения, которое ее создало, @tablename - это таблица, хранящаяся в памяти и живущая в течение времени жизни пакета / процедуры который создал его, как локальная переменная.

Вы можете добавить (не PK) индекс только к таблице #temp.

create table #blah (fld int)
create nonclustered index idx on #blah (fld)
3 голосов
/ 17 июня 2011

Это не полный ответ, но #table создаст временную таблицу, которую вам нужно удалить, или она сохранится в вашей базе данных.@table - это табличная переменная, которая не будет сохраняться дольше, чем ваш скрипт.

Кроме того, я думаю, что этот пост ответит на другую часть вашего вопроса.

Создание индекса длятабличная переменная

2 голосов
/ 17 июня 2011

Да, вы можете создавать индексы для временных таблиц или табличных переменных.http://sqlserverplanet.com/sql/create-index-on-table-variable/

...