para este caso específico, que tentarei explicar abaixo, o uso de uma variável de tabela tem um desempenho melhor do que não o uso de uma variável de tabela.
Gostaria de saber por que e, se possível, livrar-se da variável da tabela.
esta é a consulta usando a variável de tabela:
USE [BISource_UAT]
GO
set statistics io on
SET STATISTICS TIME ON
SET NOCOUNT ON;
DECLARE @OrderStartDate DATETIME = '15-feb-2015'
DECLARE @OrderEndDate DATETIME = '28-feb-2016'
DECLARE @tmp TABLE
(
strBxOrderNo VARCHAR(20)
,sintReturnId INT
)
INSERT INTO @tmp
SELECT strBxOrderNo
,sintReturnId
FROM TABLEBACKUPS.dbo.tblBReturnHistory rh
WHERE rh.sintReturnStatusId in ( 3 )
AND rh.dtmAdded >= @OrderStartDate
AND rh.dtmAdded < @OrderEndDate
SELECT
op.lngPaymentID
,op.strBxOrderNo
,op.sintPaymentTypeID
,op.strCurrencyCode
,op.strBCCurrencyCode
,op.decPaymentAmount
,op.decBCPaymentAmount
,ap.strAccountCode
,o.sintMarketID
,o.sintOrderChannelID
,o.sintOrderTypeID
,CASE WHEN opgv.lngpaymentID IS NULL THEN NULL
-- Not a Voucher = Null
WHEN gvp.strIssuedBxOrderNo IS NULL THEN 0 ELSE 1
END AS [IsPromoVoucher] -- Is a Voucher - check type
,o.sdtmOrdCreated
FROM @tmp rh
INNER JOIN TABLEBACKUPS.dbo.tblBReturn r
ON r.sintReturnId = rh.sintReturnId
AND r.strBxOrderNo = rh.strBxOrderNo
INNER JOIN bocss2.dbo.tblBOrder o
ON o.strBxOrderNo = r.strBxOrderNo
INNER JOIN Bocss2.dbo.tblBOrderPayment op
ON op.strBxOrderNo = o.strBxOrderNo
INNER JOIN TABLEBACKUPS.dbo.tblBOrderItemReturn AS oir
ON r.sintReturnId = oir.sintReturnID
AND r.strBxOrderNo = oir.strBxOrderNo
INNER JOIN Bocss2.dbo.tblBOrderItem AS i
ON i.strBxOrderNo = oir.strBxOrderNo
AND i.sintOrderSeqNo = oir.sintOrderSeqNo
INNER JOIN TABLEBACKUPS.dbo.tblBAccountParticipant ap
ON o.lngAccountParticipantID = ap.lngParticipantID
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBOrderPaymentGiftVoucher opgv
ON op.lngPaymentID = opgv.lngPaymentID
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBGiftVoucher gv
ON opgv.strVoucherNumber = gv.strVoucherNumber
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBGiftVoucherPromotion gvp
ON gvp.strIssuedBxOrderNo = gv.strIssuedBxOrderNo
WHERE oir.decReturnFinalAmount > 0
AND o.sdtmOrdCreated >= @OrderStartDate
isso produz as seguintes estatísticas:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 78 ms, elapsed time = 86 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table '#BF0B2154'. Scan count 0, logical reads 1957, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBReturnHistory'. Scan count 1, logical reads 13, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 9 ms.
Table 'tblBGiftVoucherPromotion'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBGiftVoucher'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderPaymentGiftVoucher'. Scan count 0, logical reads 452, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderItem'. Scan count 0, logical reads 904, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderPayment'. Scan count 186, logical reads 1649, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBAccountParticipant'. Scan count 0, logical reads 7112, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrder'. Scan count 3557, logical reads 14267, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderItemReturn'. Scan count 1951, logical reads 5865, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBReturn'. Scan count 0, logical reads 3902, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table '#BF0B2154'. Scan count 1, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 125 ms, elapsed time = 138 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
usando showplan_text em eu gostaria de mostrar o plano de consulta:
primeira parte da consulta - preenchendo a variável da tabela
segunda parte da consulta: usando a tabela varible e juntando as outras tabelas:
Este é o plano XML da consulta usando a variável de tabela.
agora esta é a mesma consulta que NÃO está usando uma variável de tabela:
USE [BISource_UAT]
GO
set statistics io on
SET STATISTICS TIME ON
SET NOCOUNT ON;
DECLARE @OrderStartDate DATETIME = '15-feb-2015'
DECLARE @OrderEndDate DATETIME = '28-feb-2016'
SELECT
op.lngPaymentID
,op.strBxOrderNo
,op.sintPaymentTypeID
,op.strCurrencyCode
,op.strBCCurrencyCode
,op.decPaymentAmount
,op.decBCPaymentAmount
,ap.strAccountCode
,o.sintMarketID
,o.sintOrderChannelID
,o.sintOrderTypeID
,CASE WHEN opgv.lngpaymentID IS NULL
THEN NULL -- Not a Voucher = Null
WHEN gvp.strIssuedBxOrderNo IS NULL
THEN 0 ELSE 1 END AS [IsPromoVoucher]
-- Is a Voucher - check type
,o.sdtmOrdCreated
FROM TABLEBACKUPS.dbo.tblBReturnHistory rh
INNER JOIN TABLEBACKUPS.dbo.tblBReturn r
ON r.sintReturnId = rh.sintReturnId
AND r.strBxOrderNo = rh.strBxOrderNo
INNER JOIN bocss2.dbo.tblBOrder o
ON o.strBxOrderNo = r.strBxOrderNo
AND o.sdtmOrdCreated >= @OrderStartDate
INNER JOIN Bocss2.dbo.tblBOrderPayment op
ON op.strBxOrderNo = o.strBxOrderNo
INNER JOIN TABLEBACKUPS.dbo.tblBOrderItemReturn AS oir
ON r.sintReturnId = oir.sintReturnID
AND r.strBxOrderNo = oir.strBxOrderNo
AND oir.decReturnFinalAmount > 0
INNER JOIN Bocss2.dbo.tblBOrderItem AS i
ON i.strBxOrderNo = oir.strBxOrderNo
AND i.sintOrderSeqNo = oir.sintOrderSeqNo
INNER JOIN TABLEBACKUPS.dbo.tblBAccountParticipant ap
ON o.lngAccountParticipantID = ap.lngParticipantID
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBOrderPaymentGiftVoucher opgv
ON op.lngPaymentID = opgv.lngPaymentID
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBGiftVoucher gv
ON opgv.strVoucherNumber = gv.strVoucherNumber
LEFT OUTER JOIN TABLEBACKUPS.dbo.tblBGiftVoucherPromotion gvp
ON gvp.strIssuedBxOrderNo = gv.strIssuedBxOrderNo
WHERE rh.sintReturnStatusId in ( 3 )
AND rh.dtmAdded >= @OrderStartDate
AND rh.dtmAdded < @OrderEndDate
ao dar uma olhada nas estatísticas, é isso que temos:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBGiftVoucher'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBAccountParticipant'. Scan count 1, logical reads 32, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBReturn'. Scan count 1, logical reads 170, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderItemReturn'. Scan count 0, logical reads 35849, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderPayment'. Scan count 9408, logical reads 87643, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderItem'. Scan count 1950, logical reads 8336, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrder'. Scan count 1951, logical reads 7835, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBReturnHistory'. Scan count 1, logical reads 13, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBOrderPaymentGiftVoucher'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tblBGiftVoucherPromotion'. Scan count 1, logical reads 27, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 625 ms, elapsed time = 612 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
Agora, em relação ao plano de execução em formato de texto:
definindo os parâmetros
Agora a parte importante, executando o show:
Este é o plano XML da consulta que NÃO está usando a variável de tabela.
Mas como, usando a variável de tabela, obtive menos leituras, menos E / S e a execução (sem limpar o cache) sempre foi mais rápida?
Eu posso fornecer qualquer script de criação de tabela ou qualquer outra coisa necessária para uma melhor compreensão dessa situação.
basta postar qualquer comentário aqui e eu responderei.
esta é uma pergunta semelhante:
ao executar as consultas após o CHECKPOINT ; DBCC DROPCLEANBUFFERS ; os resultados foram:
consulta com variável de tabela
consulta sem variável de tabela