План выполнения над запросом с временными таблицами - PullRequest
5 голосов
/ 11 января 2012

У меня есть хранимая процедура, которая делает что-то вроде этого:

SELECT Id
INTO #temp
FROM table
WHERE ...

DELETE FROM #temp
INNER JOIN table2 ON a=b
WHERE ...

Но он работает медленно. Когда я пытаюсь просмотреть план выполнения, я не могу, поскольку SQL Server Management Studio говорит: «Сообщение 208, уровень 16, состояние 0, строка 31 Неверное имя объекта« #temp ».»

Есть ли способ просмотреть план выполнения (или подробности выполнения (не план)) для такого сценария?

Ответы [ 4 ]

5 голосов
/ 11 января 2012

SET SHOWPLAN_TEXT ON (или щелкнув по Просмотр оценочного плана выполнения - SSMS) создает план вместо выполнения SQL

Так как это создает # temp

SELECT Id
INTO #temp
FROM table
WHERE ...

это не удастся

DELETE FROM #temp
INNER JOIN table2 ON a=b
WHERE ...

Таким образом, решение состоит в том, чтобы добавить это к вершине (или сделать эквивалент через SSMS)

SET SHOWPLAN_TEXT OFF
GO

SET STATISTICS PROFILE ON
GO
2 голосов
/ 11 января 2012

Это должно позволить вам увидеть примерный план выполнения для первого оператора штрафа.

Для второго оператора сначала необходимо создать и заполнить таблицу #temp (важно заполнить ее, чтобы она показывала план, который будет использоваться для правильного числа строк).

(или, конечно, вы можете просто включить опцию «Включить фактический план выполнения» в SSMS и запустить все это, если вы не пытаетесь просмотреть предполагаемый план)

1 голос
/ 11 января 2012

Вы можете использовать этот оператор перед выполнением запроса

   SET STATISTICS PROFILE ON
   SELECT Id
   INTO #temp
   FROM table
   WHERE ...

   DELETE FROM #temp
  INNER JOIN table2 ON a=b
  WHERE ...
1 голос
/ 11 января 2012

Оптимизатор, который используется для генерации планов предполагаемого выполнения, не выполняет T-SQL. Он выполняет операторы через algebrizer, процесс, описанный ранее, который отвечает за проверку имен объектов базы данных.

Поскольку запрос еще не выполнен, временная таблица еще не существует. Это является причиной ошибки.


Один из способов решить эту проблему (и протестировать план выполнения) - создать таблицу #temp и создать в хранимой процедуре insert into вместо select ... into.

...