Yaklaşık 70.000 satır ve iki sütun (her ikisi de VARCHAR(16)
): id
ve parent_id
'dan oluşan bir tablom var.Nesne hiyerarşisinin derinliğini belirlemek için CTE ve T-SQL döngüsü
Belirli bir kaydın "kök" düğümden ne kadar uzakta olduğunu gösteren bir 'derinlik' sütununu doldurmak istiyorum.
örn. Yukarıda çalıştırmak için yaklaşık iki saat sürer benim veri kümesi ile
WITH myCTE(id, depth) AS
(
SELECT id, 0 FROM objects where id = 'A'
UNION ALL
SELECT objects.id, depth + 1 FROM myCTE JOIN objects ON objects.parent_id = myCTE.id
)
SELECT id, depth FROM myCTE
(~ 80.000 satır):
id,parent_id,depth
A,NULL,0
B,A,1
C,A,1
D,B,2
E,D,3
vb
Ben benzer bir soruya this answer dayalı bir sorgu yazarak başladı !Sonra bir döngü olarak benim sorgu yazdım ve çok daha iyi bir performans var:
ALTER TABLE objects ADD depth INT NULL
DECLARE @counter int
DECLARE @total int
SET @counter = 0
UPDATE objects SET depth = 0 WHERE id = 'A'
SELECT @total = COUNT(*) FROM objects WHERE depth IS NULL
WHILE (@total > 0)
BEGIN
UPDATE objects SET depth = @counter + 1 WHERE parent_id IN (
SELECT id FROM objects WHERE depth = @counter
)
SELECT @total = COUNT(*) FROM objects WHERE depth IS NULL
SET @counter = @counter + 1
END
Yukarıdaki kod sadece birkaç dakika sürer (ve mevcut tabloya sonuçlar ekleyerek yararlanabileceği)
Sorunun, sonuçların bu sorun için CTE kullanmanın tipik bir yolu olup olmadığını veya gözden kaçırdığım bir şey olup olmadığını açıklayıp açıklamamasıdır. Endeksler, belki? (Şu anda masada hiç yok)
Vay. Benim tecrübemde, bu oldukça tipik olmayan sesler. İkisi arasında bir karşılaştırma görmek için yürütme planlarını açmak zorunda mıyım? – Matt
@Matt - Orta büyüklükteki büyük tablolarda, CTE'nin yineleyici kısmının bir indeks aramasıyla veya [Performansın korkunç bir şekilde bozulmasına neden olabilir] tarafından karşılanabilmesi kritik öneme sahiptir (http://dba.stackexchange.com/q/15596/ 3690) –