1'den 400'e kadar 400 satır içeren aşağıdaki yığın tablosu göz önüne alındığında:
DROP TABLE IF EXISTS dbo.N;
GO
SELECT
SV.number
INTO dbo.N
FROM master.dbo.spt_values AS SV
WHERE
SV.[type] = N'P'
AND SV.number BETWEEN 1 AND 400;
ve aşağıdaki ayarlar:
SET NOCOUNT ON;
SET STATISTICS IO, TIME OFF;
SET STATISTICS XML OFF;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Aşağıdaki SELECT
ifade yaklaşık 6 saniye içinde tamamlanır ( demo , plan ):
DECLARE @n integer = 400;
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Not: @ OPTIMIZE FOR
Madde sadece çeşitli nedenlerle ortaya çıkabilecek bir kardinalite yanlışlığı da dahil olmak üzere gerçek sorunun temel ayrıntılarını yakalayan makul büyüklükte bir repro üretmek içindir.
Tek satırlık çıktı bir tabloya yazıldığında, 19 saniye sürer ( demo , plan ):
DECLARE @T table (c bigint NOT NULL);
DECLARE @n integer = 400;
INSERT @T
(c)
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Yürütme planları, bir satırın eklenmesiyle aynı görünür.
Tüm ekstra zamanlar CPU kullanımı tarafından tüketilmiş gibi görünüyor.
İfade neden INSERT
bu kadar yavaş?