Birkaç avuç skaler agregayı açan aşağıdaki sorguyu düşünün:
SELECT A, B
FROM (
SELECT
MAX(CASE WHEN ID = 1 THEN 1 ELSE 0 END) VAL1
, MAX(CASE WHEN ID = 2 THEN 1 ELSE 0 END) VAL2
, MAX(CASE WHEN ID = 3 THEN 1 ELSE 0 END) VAL3
, MAX(CASE WHEN ID = 4 THEN 1 ELSE 0 END) VAL4
, MAX(CASE WHEN ID = 5 THEN 1 ELSE 0 END) VAL5
, MAX(CASE WHEN ID = 6 THEN 1 ELSE 0 END) VAL6
, MAX(CASE WHEN ID = 7 THEN 1 ELSE 0 END) VAL7
, MAX(CASE WHEN ID = 16 THEN 1 ELSE 0 END) VAL16
FROM dbo.PARALLEL_ZONE_REPRO
) q
UNPIVOT(B FOR A IN (
VAL1
,VAL2
,VAL3
,VAL4
,VAL5
,VAL6
,VAL7
,VAL16
)) U
OPTION (MAXDOP 4);
SQL Server 2017'de, iki paralel dalı olan bir plan alıyorum. Sol paralel dal bana yerinde hissetmiyor. Optimize edici, global skaler agregattan yalnızca tek bir satır çıkışı olacağının garantisine sahiptir, ancak bunun ana operatörü, yuvarlak robin bölümlemeli bir Dağıtma Akışıdır:
Sorguyu yürüttüğümde tüm satırlar beklendiği gibi tek bir iş parçacığına gider. Bu sorgu ile herhangi bir performans sorunu yok, ancak sorgu 4 olarak ayarlanmış MAXDOP ile 8 paralel iş parçacıkları ayırır. Yine, bunun yerinde olduğunu hissediyorum. Her iki paralel dalın aynı anda yürütülmesi imkansızdır. TF 2467 zamanlayıcı algoritması başına zamanlayıcı iş parçacığı sayısına bakmak için değiştiren TF 2467 etkin olduğundan gereksiz işçi iş parçacığı rezervasyon önlemek istiyorum.
Sorgu, tablo taraması ve yerel toplamı içeren tam olarak bir paralel dal olacak şekilde yeniden yazılabilir mi? Örneğin, iç içe döngü bir seri bölgede yürütmek istiyorum dışında genel şekli ile iyi olurdu:
Application Reasons ™ için bu sorguyu parçalara ayırmaktan kesinlikle kaçınmayı tercih ederim. İsterseniz, gerçek sorgu planını burada görüntüleyebilirsiniz . Evde oynamak istiyorsanız, sorguda kullanılan tabloyu oluşturmak için T-SQL:
DROP TABLE IF EXISTS dbo.PARALLEL_ZONE_REPRO;
CREATE TABLE dbo.PARALLEL_ZONE_REPRO (
ID BIGINT,
FILLER VARCHAR(100)
);
INSERT INTO dbo.PARALLEL_ZONE_REPRO WITH (TABLOCK)
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) % 15
, REPLICATE('Z', 100)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;