para este caso específico, que trataré de explicar a continuación, usar una variable de tabla funciona mejor que no usar una variable de tabla.
Me gustaría saber por qué, y si es posible, deshacerme de la variable de tabla.
Esta es la consulta usando la variable de tabla:
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
esto produce las siguientes estadí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 en Me gustaría mostrar el plan de consulta:
primera parte de la consulta: completar la variable de tabla
segunda parte de la consulta: usando la variable de tabla y uniendo las otras tablas:
Este es el plan XML de la consulta usando la variable de tabla.
ahora esta es la misma consulta que NO usa una variable de tabla:
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
Al echar un vistazo a las estadísticas, esto es lo que tenemos:
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.
Ahora, con respecto al plan de ejecución en formato de texto:
establecer los parámetros
Ahora la parte importante, ejecutar el espectáculo:
Este es el plan XML de la consulta que NO utiliza la variable de tabla.
Pero, ¿por qué al usar la variable de tabla obtuve menos lecturas, menos E / S y la ejecución (sin borrar el caché) siempre ha sido más rápida?
Puedo proporcionar cualquier script de creación de tabla, o cualquier otra cosa necesaria para una mejor comprensión de esta situación.
simplemente publique cualquier comentario aquí y le responderé.
Esta es una pregunta similar:
al ejecutar las consultas después de CHECKPOINT ; DBCC DROPCLEANBUFFERS ; los resultados fueron:
consulta con variable de tabla
consulta sin variable de tabla