SORU
14 AĞUSTOS 2008, PERŞEMBE


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
18 NİSAN 2010, Pazar


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...

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • hydejiaqi

    hydejiaqi

    12 Mart 2008
  • Vsauce

    Vsauce

    30 Temmuz 2007
  • Within Temptation

    Within Tempt

    18 EYLÜL 2006