Обновление № 2:
Я хочу добавить еще один шаг, который должен прояснить все. После создания информации о плане выполните следующую инструкцию (с правильным дескриптором плана), чтобы посмотреть XML ShowPlan.
DECLARE @val as VARBINARY(64)
-- NOTE: Replace the Hex string with the current plan_handle !
SET @val = CONVERT(VARBINARY(64), 0x05001300045A3D02B801BE11000000000000000000000000)
SELECT * FROM sys.dm_exec_query_plan(@val)
Просмотр сгенерированного XML показывает, что существует 2 элемента QueryPlan, 2 или более элементов StmtSimple / StmtCond и всего 1 пакетный пакет. Как упоминает gbn , существует разница между «планами выполнения» и «планами запросов». Похоже, это делает кристально ясным, какие части мы на самом деле просматриваем во всех запросах sys.dm_ .
sys.dm_exec_query_stats в MSDN, SQL 2008
sys.dm_exec_query_plan в MSDN, SQL 2008
Таким образом, со всей этой информацией, возвращенный plan_handle является Планом выполнения; и части являются элементами плана запроса.
-
Обновление:
После комментария Эндрю я еще раз проверил, и действительно, дескрипторы плана запроса совпадают. И, чтобы быть уверенным, я создал дубликат хранимой процедуры, изменив только имя, и перезапустил свой тест для этой хранимой процедуры. Это также привело к созданию нового набора частей запроса, которые совместно использовали один и тот же дескриптор плана.
Итак, ответ gbn кажется правильным, по крайней мере, с тем, что я здесь тестировал. Интересные вещи.
-
Последняя цитата из Герт Дрэперс, похоже, неверна - вот мой тест. Я использую SQL 2005 здесь. В моем тесте я вижу 2 плана запросов, сгенерированных для разных частей одной и той же хранимой процедуры.
Сначала я создал две таблицы: tblTag1 и tblTagWithGUID . Я сделал их несколько похожими, чтобы моя хранимая процедура могла чередоваться между любой таблицей и возвращать результаты с идентичным расположением таблицы результатов.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
-- Table #1, tblTag1
CREATE TABLE [dbo].[tblTag1](
[id] [int] IDENTITY(1,1) NOT NULL,
[createDate] [datetime] NOT NULL CONSTRAINT [DF_tblTag1_createDate] DEFAULT (getdate()),
[someTag] [varchar](100) NOT NULL,
CONSTRAINT [PK_tblTag1] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Table #2, tblTagWithGUID
CREATE TABLE [dbo].[tblTagWithGUID](
[id] [int] IDENTITY(1,1) NOT NULL,
[createDate] [datetime] NOT NULL CONSTRAINT [DF_tblTagWithGUID_createDate] DEFAULT (getdate()),
[someTag] [varchar](100) NOT NULL,
[someGUID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_tblTagWithGUID_someGUID] DEFAULT (newid()),
CONSTRAINT [PK_tblTagWithGUID] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Во-вторых, хранимая процедура. В хранимой процедуре я выбираю одну или другую таблицу в зависимости от аргумента.
CREATE PROCEDURE spLoadTags
@Pick AS BIT = NULL
AS
BEGIN
IF @Pick = 0
SELECT id, createDate, someTag FROM tblTag1
IF @Pick = 1
SELECT id, createDate, someTag FROM tblTagWithGUID
END
Я добавил некоторые данные в каждую таблицу - затем запустил хранимую процедуру несколько десятков раз с аргументами 0 или 1.
Затем я запустил этот запрос, чтобы проверить сгенерированные планы запросов. Извините, если кто-то здесь обиделся за мою неряшливость - конечно, это не рабочий код.
WITH PlanData AS
(
SELECT
(SELECT SUBSTRING(text, statement_start_offset/2 + 1,
(CASE WHEN statement_end_offset = -1
THEN LEN(CONVERT(nvarchar(MAX),text)) * 2
ELSE statement_end_offset
END - statement_start_offset)/2)
FROM sys.dm_exec_sql_text(sql_handle) WHERE [text] like '%SELECT id, createDate, someTag FROM tblTag%') AS query_text,
plan_handle
FROM sys.dm_exec_query_stats
)
SELECT
DISTINCT
execution_count,
PlanData.query_text,
sys.dm_exec_query_stats.plan_handle
FROM sys.dm_exec_query_stats, PlanData
WHERE
sys.dm_exec_query_stats.plan_handle = PlanData.plan_handle and
PlanData.query_text IS NOT NULL
ORDER BY execution_count DESC
Когда я запускаю этот запрос, я вижу кучу планов, но поскольку я запустил хранимую процедуру несколько десятков раз, отдельные части оказываются вверху.
execution_count query_text plan_handle
96 SELECT id, createDate, someTag FROM tblTag1 0x05001200045A3D02B8613E13000000000000000000000000
96 SELECT id, createDate, someTag FROM tblTagWithGUID 0x05001200045A3D02B8613E13000000000000000000000000
Я включил только эти две строки, но, надеюсь, это достаточно просто, когда кто-то еще может проверить мои результаты. Вы можете увидеть другие строки, если вы используете инструмент управления SQL, как я; предположительно вызвано просмотром таблиц или другими действиями.