Sayılar SQL Yardımcı tablo
Sql sorgu belirli türleri için, sayıların yardımcı bir tablo çok yararlı olabilir. Satır, her sorgu için gerekli sayısını verir bu satırları bir kullanıcı olarak, belirli bir iş için ihtiyaç olarak tanımlanan fonksiyonu ile bir tablo olarak oluşturulabilir.
Böyle bir işlevi oluşturmak için en iyi yolu nedir?
CEVAP
Heh... bu kadar geciktiğim için eski bir mesaja cevap veriyorum. Ve, evet, vardı cevap çünkü en popüler cevap (zaman, Özyinelemeli CTE cevap ile bağlantı için 14 farklı yöntem) bu konuyu, ummm... performans meydan en iyi ihtimalle.
İlk olarak, madde ile 14 farklı çözümler iyi görmek için farklı yöntemler oluşturma Numaraları/Taksitli masada sinek ama gösterilen makaleyi ve anılan iş parçacığı varçokönemli alıntı...
"öneriler verimliliği ile ilgili ve performans genellikle özneldir. Bir sorgu olarak ne olursa olsun kullanılan fiziksel uygulaması belirleyen bir sorgu verimliliği. Bu nedenle, güvenmek yerine kurallar önyargılı, zorunludur sorguyu test ve belirleyen hangisi daha iyi yapar."
İronik olarak, maddenin kendisini çok öznel ifadeleri ve "kurallar" gibi . önyargılı içerir ^em>"bir numara oluşturabilir CTE özyinelemelioldukça verimli"ve"Buetkili bir yöntemBen-Gen Itzik tarafından bir haber gönderilmesini SÜRE döngü kullanarak"sadece karşılaştırma amaçlı göndermiş eminim. Hadi Millet... ben Sadece söz Itzik güzel isim aslında bu korkunç yöntemi kullanarak bazı zavallı miskin neden olabilir. Yazar o vaaz ne pratik olmalıdır ve özellikle herhangi bir scalablility karşısında böyle gülünç bir yanlış açıklamaları yapmadan önce küçük bir performans testi yapmak gerekir.
Aslında herhangi bir kod mu ne ya da ne birisi hakkında herhangi bir öznel iddiaları yapmadan önce bazı testler yapmak düşüncesi ile"", burada kendi test yapabileceğiniz bir şifre seviyor. Kur profiler ve kendiniz kontrol edin... sadece bir test kaçıyorsun "Arama & 'Replace" senin için numarasını 1000000 "favori" numarası
--===== Test for 1000000 rows ==================================
GO
--===== Traditional RECURSIVE CTE method
WITH Tally (N) AS
(
SELECT 1 UNION ALL
SELECT 1 N FROM Tally WHERE N < 1000000
)
SELECT N
INTO #Tally1
FROM Tally
OPTION (MAXRECURSION 0);
GO
--===== Traditional WHILE LOOP method
CREATE TABLE #Tally2 (N INT);
SET NOCOUNT ON;
DECLARE @Index INT;
SET @Index = 1;
WHILE @Index <= 1000000
BEGIN
INSERT #Tally2 (N)
VALUES (@Index);
SET @Index = @Index 1;
END;
GO
--===== Traditional CROSS JOIN table method
SELECT TOP (1000000)
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS N
INTO #Tally3
FROM Master.sys.All_Columns ac1
CROSS JOIN Master.sys.ALL_Columns ac2;
GO
--===== Itzik's CROSS JOINED CTE method
WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
E02(N) AS (SELECT 1 FROM E00 a, E00 b),
E04(N) AS (SELECT 1 FROM E02 a, E02 b),
E08(N) AS (SELECT 1 FROM E04 a, E04 b),
E16(N) AS (SELECT 1 FROM E08 a, E08 b),
E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
SELECT N
INTO #Tally4
FROM cteTally
WHERE N <= 1000000;
GO
--===== Housekeeping
DROP TABLE #Tally1, #Tally2, #Tally3, #Tally4;
GO
Sırası gelmişken, burada 100,, 1000 10000, 100000 ve 1000000... değerleri için SQL Profiler aldığım numaraları
SPID TextData Dur(ms) CPU Reads Writes
---- ---------------------------------------- ------- ----- ------- ------
51 --===== Test for 100 rows ============== 8 0 0 0
51 --===== Traditional RECURSIVE CTE method 16 0 868 0
51 --===== Traditional WHILE LOOP method CR 73 16 175 2
51 --===== Traditional CROSS JOIN table met 11 0 80 0
51 --===== Itzik's CROSS JOINED CTE method 6 0 63 0
51 --===== Housekeeping DROP TABLE #Tally 35 31 401 0
51 --===== Test for 1000 rows ============= 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 47 47 8074 0
51 --===== Traditional WHILE LOOP method CR 80 78 1085 0
51 --===== Traditional CROSS JOIN table met 5 0 98 0
51 --===== Itzik's CROSS JOINED CTE method 2 0 83 0
51 --===== Housekeeping DROP TABLE #Tally 6 15 426 0
51 --===== Test for 10000 rows ============ 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 434 344 80230 10
51 --===== Traditional WHILE LOOP method CR 671 563 10240 9
51 --===== Traditional CROSS JOIN table met 25 31 302 15
51 --===== Itzik's CROSS JOINED CTE method 24 0 192 15
51 --===== Housekeeping DROP TABLE #Tally 7 15 531 0
51 --===== Test for 100000 rows =========== 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 4143 3813 800260 154
51 --===== Traditional WHILE LOOP method CR 5820 5547 101380 161
51 --===== Traditional CROSS JOIN table met 160 140 479 211
51 --===== Itzik's CROSS JOINED CTE method 153 141 276 204
51 --===== Housekeeping DROP TABLE #Tally 10 15 761 0
51 --===== Test for 1000000 rows ========== 0 0 0 0
51 --===== Traditional RECURSIVE CTE method 41349 37437 8001048 1601
51 --===== Traditional WHILE LOOP method CR 59138 56141 1012785 1682
51 --===== Traditional CROSS JOIN table met 1224 1219 2429 2101
51 --===== Itzik's CROSS JOINED CTE method 1448 1328 1217 2095
51 --===== Housekeeping DROP TABLE #Tally 8 0 415 0
Gördüğünüz gibiÖzyinelemeli CTE yöntemi yalnızca Süre ve CPU için İse Döngü için ikinci en kötü ve baskı Sırasında Döngü daha okur 8 kat daha fazla bellek vardır. Steroid RBAR ve Döngü Kaçınılması gerektiği gibi, ne pahasına olursa olsun, herhangi bir tek satır hesaplamalar için kaçınılmalıdır.Özyineleme oldukça değerli olan yerler de var ama bu onlardan biri DEĞİL.
Yan bar Denny kesinlikle nokta... doğru boyutta kalıcı Numaraları veya Taksitli bir tablo gibi birçok şey için gitmek için yol. Doğru boyutta ne anlama geliyor? Çoğu insan Çetele tablosu tarihleri oluşturmak için böler veya VARCHAR(8000) yapmak için kullanın. Eğer oluşturduğunuz bir 11,000 satır Taksitli tablo ile doğru kümelenmiş dizin üzerinde "N", yeterli satır oluşturmak için daha 30 yıl değerinde tarihleri (ben iş ile ipotek adil bir bit yani 30 yıldır bir anahtar numara benim için) ve kesinlikle yeterince tanıtıcı bir İKİLİK(8000) bölünmüş. Neden "doğru boyutlandırma" kadar önemli? Eğer Taksitli tablo çok kullanılırsa, kolayca bellek üzerinde fazla baskı olmadan cayır cayır yanan hızlı yapar önbellek tüm uyuyor.
Son ama en az değil, her biri bilir ki eğer oluşturduğunuz bir kalıcı Taksitli tablo, değil mi önemli olan yöntemi kullanmak için inşa çünkü 1) sadece olacak bir kez yapılan ve 2) Eğer bir şey gibi bir 11,000 satır tablo, tüm yöntemleri kaçacak "yeterince iyi".Neden gelir benim için tüm indigination???
Cevap bu zavallı adam/gal kim iyiyi kötüyü bilemez ve sadece ihtiyaçlarını almak onun işi olabilir görmek gibi bir şey Özyinelemeli CTE yöntemi ve karar için bir şey çok daha büyük ve çok daha sık kullanılan bir bina daha kalıcı Taksitli tablo ve çalışıyorumbu sunuculardaki verilerin sahibi olan bu insanlar, kendi kodu üzerinde çalışan sunucuları ve şirket korumak. Evet. bu önemli bir şey. Herkes için iyi olmalıdır. Bir şeyler yapmak için doğru yolu öğretmek yerine". yeterince iyi Biraz önce test gönderme veya bir şeyi kullanarak bir yazı veya kitap... hayat kurtarabilir, hatta kendi özellikle eğer sence bir özyinelemeli CTE yol gitmek gibi bir şey bu. ;-)
Dinlediğiniz için teşekkür ederim...
Nasıl parola tuz gökkuşağı tablo saldı...
Nasıl açıkça bir Modeli'Raylar ta...
Update deyimi tablo diğer adı kullanma...
Konumlandırma lateks tablo...
Bir SQLite tablo Django kullanarak bin...