FIZZBUZZ testinin SQL Server'da yapılmasında en etkili yöntem nedir?


28

Bu tamamen konuyla ilgili olmayabilir, ancak burada yavaş bir gün.

Sözcüğünü ihtiva eden bir sütun ile 1 ile 49 arasında bir sayı listesini elde etmek için daha verimli bir yöntem var FIZZsayıda eşit 3'e göre ayrılabilir zaman BUZZsayısı eşit 5 ile ayrılabilir ve FIZZBUZZsayısı eşit ayrılabilir zaman tarafından hem 3 ile 5?

Denemelerim: (DİKKAT, bu işlem önbellekinizi boşaltacaktır, bu yüzden bir ÜRETİM KUTUSU ÇALIŞTIRMAYIN):

DBCC FREEPROCCACHE
GO
/*VARIANT1*/
;WITH t AS (
    SELECT RowNum = ROW_NUMBER() OVER (ORDER BY o.object_id)
    FROM sys.objects o
)
SELECT t.RowNum
    , CASE WHEN ((t.RowNum % 3) + (t.RowNum % 5)) = 0  THEN 'FIZZBUZZ' 
    ELSE 
        CASE WHEN t.RowNum % 3 = 0 THEN 'FIZZ' 
        ELSE 
            CASE WHEN t.RowNum % 5 = 0 THEN 'BUZZ' 
            ELSE '' 
            END 
        END 
    END
FROM t
WHERE t.RowNum < 50;
GO 100

/*VARIANT2*/
DECLARE @t TABLE
(
    Num INT NOT NULL PRIMARY KEY CLUSTERED
);
INSERT INTO @t (Num)
SELECT ROW_NUMBER() OVER (ORDER BY o.object_id)
FROM sys.objects o;

SELECT t.Num
    , CASE WHEN ((t.Num % 3) + (t.Num % 5)) = 0  THEN 'FIZZBUZZ' 
    ELSE 
        CASE WHEN t.Num % 3 = 0 THEN 'FIZZ' 
        ELSE 
            CASE WHEN t.Num % 5 = 0 THEN 'BUZZ' 
            ELSE '' 
            END 
        END 
    END
FROM @t t
WHERE t.Num < 50;
GO 100

SELECT CASE WHEN dest.text LIKE '%/*VARIANT1*/%' THEN 'VARIANT1' ELSE 'VARIANT2' END
    , MAX(deqs.execution_count)
    , SUM(deqs.total_worker_time)
    , AvgWorkerTime = SUM(deqs.total_worker_time) / MAX(deqs.execution_count)
FROM sys.dm_exec_query_stats deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) dest
WHERE (dest.text LIKE '%/*VARIANT1*/%'
    OR dest.text LIKE '%/*VARIANT2*/%')
    AND dest.text NOT LIKE '%/*NOT_ME!*/%'
GROUP BY CASE WHEN dest.text LIKE '%/*VARIANT1*/%' THEN 'VARIANT1' ELSE 'VARIANT2' END
ORDER BY CASE WHEN dest.text LIKE '%/*VARIANT1*/%' THEN 'VARIANT1' ELSE 'VARIANT2' END
/*NOT_ME!*/;

@AaronBertrand tarafından önerildiği gibi, her bir deyim kümesini her biri 100 kez çalıştırma girişimlerimi değiştirdim, daha sonra SQL Server tarafından kaydedilen süreleri gösterdim sys.dm_exec_query_stats.

Sonuçlar:

            Runs    total_time      average time
VARIANT1    100     42533           425
VARIANT2    100     138677          1386

Yanıtlar:


3

Aşağıda ilk milyon sayıyı temp tablosuna yazan bir T-SQL çözümü verilmiştir. Makinemde yaklaşık 84 ms sürer. Kilit tıkanıklıklar NESTING_TRANSACTION_FULL mandalını bekliyor ve CXPACKETikisi de değişme dışında nasıl adresleneceğini bilmiyorum MAXDOP. Paralel iç içe döngülerden ve talep temelli paralellikten faydalanabilecek bir sorgu planı istedim.

görüntü tanımını buraya girin

Kod biraz uzun. Kısacası, toplam 66666 satır için iki türetilmiş 246 satır ve 271 satır tablosunu birleştiriyorum. Bu sıralar, FIZZBUZZ paterninin her 15 sıra için tekrarlanması gerçeğinden yararlanan 15 sıradan türetilmiş bir masaya birleştirilir. Son on satır a ile eklenir UNION ALL.

DROP TABLE IF EXISTS #t;

SELECT res.fizzbuzz INTO #t
FROM
(
VALUES
(0),
(15),
(30),
(45),
(60),
(75),
(90),
(105),
(120),
(135),
(150),
(165),
(180),
(195),
(210),
(225),
(240),
(255),
(270),
(285),
(300),
(315),
(330),
(345),
(360),
(375),
(390),
(405),
(420),
(435),
(450),
(465),
(480),
(495),
(510),
(525),
(540),
(555),
(570),
(585),
(600),
(615),
(630),
(645),
(660),
(675),
(690),
(705),
(720),
(735),
(750),
(765),
(780),
(795),
(810),
(825),
(840),
(855),
(870),
(885),
(900),
(915),
(930),
(945),
(960),
(975),
(990),
(1005),
(1020),
(1035),
(1050),
(1065),
(1080),
(1095),
(1110),
(1125),
(1140),
(1155),
(1170),
(1185),
(1200),
(1215),
(1230),
(1245),
(1260),
(1275),
(1290),
(1305),
(1320),
(1335),
(1350),
(1365),
(1380),
(1395),
(1410),
(1425),
(1440),
(1455),
(1470),
(1485),
(1500),
(1515),
(1530),
(1545),
(1560),
(1575),
(1590),
(1605),
(1620),
(1635),
(1650),
(1665),
(1680),
(1695),
(1710),
(1725),
(1740),
(1755),
(1770),
(1785),
(1800),
(1815),
(1830),
(1845),
(1860),
(1875),
(1890),
(1905),
(1920),
(1935),
(1950),
(1965),
(1980),
(1995),
(2010),
(2025),
(2040),
(2055),
(2070),
(2085),
(2100),
(2115),
(2130),
(2145),
(2160),
(2175),
(2190),
(2205),
(2220),
(2235),
(2250),
(2265),
(2280),
(2295),
(2310),
(2325),
(2340),
(2355),
(2370),
(2385),
(2400),
(2415),
(2430),
(2445),
(2460),
(2475),
(2490),
(2505),
(2520),
(2535),
(2550),
(2565),
(2580),
(2595),
(2610),
(2625),
(2640),
(2655),
(2670),
(2685),
(2700),
(2715),
(2730),
(2745),
(2760),
(2775),
(2790),
(2805),
(2820),
(2835),
(2850),
(2865),
(2880),
(2895),
(2910),
(2925),
(2940),
(2955),
(2970),
(2985),
(3000),
(3015),
(3030),
(3045),
(3060),
(3075),
(3090),
(3105),
(3120),
(3135),
(3150),
(3165),
(3180),
(3195),
(3210),
(3225),
(3240),
(3255),
(3270),
(3285),
(3300),
(3315),
(3330),
(3345),
(3360),
(3375),
(3390),
(3405),
(3420),
(3435),
(3450),
(3465),
(3480),
(3495),
(3510),
(3525),
(3540),
(3555),
(3570),
(3585),
(3600),
(3615),
(3630),
(3645),
(3660),
(3675)
) v246 (n)
CROSS JOIN 
(
VALUES
(0),
(15),
(30),
(45),
(60),
(75),
(90),
(105),
(120),
(135),
(150),
(165),
(180),
(195),
(210),
(225),
(240),
(255),
(270),
(285),
(300),
(315),
(330),
(345),
(360),
(375),
(390),
(405),
(420),
(435),
(450),
(465),
(480),
(495),
(510),
(525),
(540),
(555),
(570),
(585),
(600),
(615),
(630),
(645),
(660),
(675),
(690),
(705),
(720),
(735),
(750),
(765),
(780),
(795),
(810),
(825),
(840),
(855),
(870),
(885),
(900),
(915),
(930),
(945),
(960),
(975),
(990),
(1005),
(1020),
(1035),
(1050),
(1065),
(1080),
(1095),
(1110),
(1125),
(1140),
(1155),
(1170),
(1185),
(1200),
(1215),
(1230),
(1245),
(1260),
(1275),
(1290),
(1305),
(1320),
(1335),
(1350),
(1365),
(1380),
(1395),
(1410),
(1425),
(1440),
(1455),
(1470),
(1485),
(1500),
(1515),
(1530),
(1545),
(1560),
(1575),
(1590),
(1605),
(1620),
(1635),
(1650),
(1665),
(1680),
(1695),
(1710),
(1725),
(1740),
(1755),
(1770),
(1785),
(1800),
(1815),
(1830),
(1845),
(1860),
(1875),
(1890),
(1905),
(1920),
(1935),
(1950),
(1965),
(1980),
(1995),
(2010),
(2025),
(2040),
(2055),
(2070),
(2085),
(2100),
(2115),
(2130),
(2145),
(2160),
(2175),
(2190),
(2205),
(2220),
(2235),
(2250),
(2265),
(2280),
(2295),
(2310),
(2325),
(2340),
(2355),
(2370),
(2385),
(2400),
(2415),
(2430),
(2445),
(2460),
(2475),
(2490),
(2505),
(2520),
(2535),
(2550),
(2565),
(2580),
(2595),
(2610),
(2625),
(2640),
(2655),
(2670),
(2685),
(2700),
(2715),
(2730),
(2745),
(2760),
(2775),
(2790),
(2805),
(2820),
(2835),
(2850),
(2865),
(2880),
(2895),
(2910),
(2925),
(2940),
(2955),
(2970),
(2985),
(3000),
(3015),
(3030),
(3045),
(3060),
(3075),
(3090),
(3105),
(3120),
(3135),
(3150),
(3165),
(3180),
(3195),
(3210),
(3225),
(3240),
(3255),
(3270),
(3285),
(3300),
(3315),
(3330),
(3345),
(3360),
(3375),
(3390),
(3405),
(3420),
(3435),
(3450),
(3465),
(3480),
(3495),
(3510),
(3525),
(3540),
(3555),
(3570),
(3585),
(3600),
(3615),
(3630),
(3645),
(3660),
(3675),
(3690),
(3705),
(3720),
(3735),
(3750),
(3765),
(3780),
(3795),
(3810),
(3825),
(3840),
(3855),
(3870),
(3885),
(3900),
(3915),
(3930),
(3945),
(3960),
(3975),
(3990),
(4005),
(4020),
(4035),
(4050)
) v271 (n)
CROSS APPLY
(
VALUES
(CAST(v246.n * 271 + v271.n + 1 AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 2 AS CHAR(8))),
(CAST('FIZZ' AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 4 AS CHAR(8))),
(CAST('BUZZ' AS CHAR(8))),
(CAST('FIZZ' AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 7 AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 8 AS CHAR(8))),
(CAST('FIZZ' AS CHAR(8))),
(CAST('BUZZ' AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 11 AS CHAR(8))),
(CAST('FIZZ' AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 13 AS CHAR(8))),
(CAST(v246.n * 271 + v271.n + 14 AS CHAR(8))),
(CAST('FIZZBUZZ' AS CHAR(8)))
) res (fizzbuzz)

UNION ALL

SELECT v.fizzbuzz
FROM (
VALUES 
('999991'),
('999992'),
('FIZZ'),
('999994'),
('BUZZ'),
('FIZZ'),
('999997'),
('999998'),
('FIZZ'),
('BUZZ')
) v (fizzbuzz)

OPTION (MAXDOP 6, NO_PERFORMANCE_SPOOL);

Bu, çözümün aslında herhangi bir hesaplama yapmaması hilesi biraz, ama o zaman aslında belirtilen bir gereklilik değildi. Bu çözüm, büyüklüğün bir göstergesi olan, dışarıdan düşünen ™ kullanır. Çıktıda iki sütunla görmek istiyorum, böylece çıktı doğru olarak daha kolay bir şekilde doğrulanabilir.
Max Vernon,

@MaxVernon Fuar noktası, sipariş edilmediğini dikkate alarak tüm satırların numarasını içermemesi gerçekten makul değildir. Düzenlemek için çekinmeyin.
Joe Obbish

15

SQL Server 2014 belleği optimize edilmiş bir masa ve yerel olarak derlenmiş bir prosedür kullanarak:

-- Setup
CREATE DATABASE InMem;
GO
ALTER DATABASE InMem
ADD FILEGROUP FG1
CONTAINS MEMORY_OPTIMIZED_DATA;
GO
ALTER DATABASE InMem
ADD FILE 
(
    NAME = 'FN1', 
    -- Change to suit your system
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQL2014\MSSQL\DATA\FN1.mod'
)
TO FILEGROUP FG1;
GO
USE InMem;
GO
CREATE TYPE dbo.FizzBuzzTableType AS TABLE 
(
    n integer NOT NULL INDEX i,
    FizzBuzz varchar(8) NOT NULL
) WITH (MEMORY_OPTIMIZED = ON);
GO

Yerel prosedür:

CREATE PROCEDURE dbo.FizzBuzz
WITH 
    NATIVE_COMPILATION, 
    SCHEMABINDING, 
    EXECUTE AS OWNER
AS
BEGIN ATOMIC 
WITH 
(
    TRANSACTION ISOLATION LEVEL = SNAPSHOT, 
    LANGUAGE = N'english'
)   
    DECLARE @n AS dbo.FizzBuzzTableType;

    DECLARE @i integer = 1;
    WHILE @i < 50
    BEGIN
        IF @i % 15 = 0
        BEGIN
            INSERT @n (n, FizzBuzz) 
            VALUES (@i, 'FizzBuzz')
        END
        ELSE 
        BEGIN
            IF @i % 3 = 0
            BEGIN
                INSERT @n (n, FizzBuzz)
                VALUES (@i, 'Fizz')
            END
            ELSE 
            BEGIN
                IF @i % 5 = 0
                BEGIN
                    INSERT @n (n, FizzBuzz) 
                    VALUES (@i, 'Buzz')
                END
                ELSE
                BEGIN
                    INSERT @n (n, FizzBuzz) 
                    VALUES (@i, CONVERT(varchar(8), @i));
                END;
            END;
        END;

        SET @i += 1;
    END;

    SELECT
        N.n, 
        N.FizzBuzz
    FROM @n AS N
    ORDER BY
        N.n;
END;

Ölçek:

SET NOCOUNT ON;
PRINT SYSUTCDATETIME();
GO
DECLARE @T AS dbo.FizzBuzzTableType;

INSERT @T (n, FizzBuzz)
EXECUTE dbo.FizzBuzz;
GO 100

PRINT SYSUTCDATETIME();

Tipik sonuçlar:

-- 95ms for 100 iterations, < 1ms each
2014-12-31 10:07:13.7993355
Beginning execution loop
Batch execution completed 100 times.
2014-12-31 10:07:13.8943409

Bu, işlem çıktısını bir bellek içi tablo değişkenine yazar, çünkü aksi takdirde sadece SSMS'deki sonuçların görüntülenme hızını test ediyoruz.

Bir milyon satır

Yukarıdaki yerel prosedür 1.000.000 numaraya ulaşması yaklaşık 12 saniye sürer . Aynı şeyi T-SQL'de yapmanın daha hızlı yolları var. Daha önce yazdığım biri. Amaçlanan paralel plana ulaşıldığında, dizüstü bilgisayarımda bir milyon satırda yaklaşık 500ms çalışır :

IF  OBJECT_ID(N'tempdb..#Result', N'U') IS NOT NULL
    DROP TABLE #Result;

IF  OBJECT_ID(N'tempdb..#Thousand', N'U') IS NOT NULL
    DROP TABLE #Thousand;

SET NOCOUNT ON;
DECLARE @start datetime2(7) = SYSUTCDATETIME();

CREATE TABLE #Thousand 
(
    n integer NOT NULL,

    CONSTRAINT PK_#Thousand
    PRIMARY KEY CLUSTERED (n)
);

-- Add 1,000 rows numbered 0-999 to #Thousand
WITH 
    L1 (n) AS
(
    SELECT  V.n
    FROM    
    (
        VALUES  (0), (1), (2), (3), (4),
                (5), (6), (7), (8), (9)
    ) AS V (n)
),
    Thousand AS
(
    SELECT  n = 
        CONVERT
        (
            integer,
            ROW_NUMBER() OVER (
            ORDER BY (SELECT NULL))
            - 1
        )
    FROM L1
    CROSS JOIN L1 AS L2
    CROSS JOIN L1 AS L3
)
INSERT #Thousand (n)
SELECT n
FROM Thousand;

-- To hold the Fizz Buzz output
CREATE TABLE #Result 
(
    n integer NOT NULL, 
    result varchar(8) NOT NULL
);

INSERT #Result
SELECT 
    Million.n, 
    Million.result
FROM
(
    -- Modulo operation to encourage few outer rows parallelism
    SELECT  n
    FROM    #Thousand
    WHERE   n % 1 = 0
) AS T1
-- Outer Apply to keep the Compute Scalar parallel
OUTER APPLY
(
    SELECT
        F2.n, 
        F2.result
    FROM #Thousand AS T2
    CROSS APPLY
    (
        -- Row numbers 1 to 1,000,000
        SELECT  (T1.n * 1000) + T2.n + 1
    ) AS F1 (n)
    CROSS APPLY
    (
        -- The Fizz Buzz bit
        SELECT
            F1.n,
            result =
                CASE 
                    WHEN F1.n % 15 = 0 THEN 'FizzBuzz'
                    WHEN F1.n % 3 = 0 THEN 'Buzz'
                    WHEN F1.n % 5 = 0 THEN 'Fizz'
                    ELSE CONVERT(varchar(8), F1.n)
                END
    ) AS F2
) AS Million
OPTION  (MAXDOP 4, QUERYTRACEON 9481);

PRINT DATEDIFF(MILLISECOND, @start, SYSUTCDATETIME());

1
"Hesaplama Skalerini paralel tutmak için Dış Uygula" dedin - bu konuda bir şeylere işaret edebilir misin?
Max Vernon

3
Hayır! Dış uygulamanın gerçekleşmesi, işlemsel skalerlerin bazen paralel alandan dışarıya taşmasını önlemeye yardımcı olabilir. Tamamen belgesiz, vb herhangi bir gün değişebilir
Paul Beyaz GoFundMonica diyor

11

Bu, makinemdeki ilk makineyle aynı işlemi yapıyor (0ms). Daha hızlı ölçeklenip ölçeklenmeyeceğinden emin değilim.

;WITH t AS (
    SELECT RowNum = ROW_NUMBER() OVER (ORDER BY o.object_id)
    FROM sys.objects o
)
SELECT t.RowNum
    , Cxa.Fizz + CxB.Buzz
FROM t
CROSS APPLY (SELECT CASE WHEN t.RowNum % 3 = 0 THEN 'FIZZ' ELSE '' END) CxA(Fizz)
CROSS APPLY (SELECT CASE WHEN t.RowNum % 5 = 0 THEN 'BUZZ' ELSE '' END) CxB(Buzz)
WHERE t.RowNum < 50;

10

Karşılaştığım en iyi sürüm makinemde 30ms'de çalışıyor:

WITH t AS (
    SELECT 1 As RowNum
    Union ALL
    Select RowNum + 1
    From t
    Where RowNum < 49
)
SELECT t.RowNum
, SubString('FIZZ', (t.RowNum % 3)*10, 5) + SubString('BUZZ', (t.RowNum % 5)*10, 5)
FROM t;

6

Sqlfiddle.com'a göre bu 7 ms sürer:

select coalesce(fizz + buzz, fizz, buzz, cast(n as varchar)) as FizzBuzz
  from (
    select n0 + 3 * n3 + 9 * n9 + 27 * n27 + 81 * n81 as n
        from
            (select 0 as n0  union all select 1 union all select 2 as n0)  as n0,
            (select 0 as n3  union all select 1 union all select 2 as n3)  as n3,
            (select 0 as n9  union all select 1 union all select 2 as n9)  as n9,
            (select 0 as n27 union all select 1 union all select 2 as n27) as n27,
            (select 0 as n81 union all select 1                    as n81) as n81
  ) as stupidalias1
  left outer join
    (select 3 as fizzstep, 'Fizz' as fizz) as stupidalias2 on n % fizzstep = 0
  left outer join
    (select 5 as buzzstep, 'Buzz' as buzz) as stupidalias3 on n % buzzstep = 0
  where n between 1 and 100
  order by n;

Hiçbir tablo, depolanmış işlem veya CTE kullanmaz.


6

~ 500-800ms'de 1 milyon sıra için çalışan yerel olarak derlenmiş depolanmış proc'un makul bir versiyonunu aldım. Bu benim gelen bitsel algorithim yaptığım bir T-SQL dönüşüm burada bitsel işlemleri Adam Machanic blog gelen küçük bir yardımla burada .

Ben (umarım) @ PaulWhite'in 500ms / 1 milyon satırlık işlemiyle aynı kuralları izliyorum, yani sonuçları oluşturuyorum ancak bunları göstermiyor / zamanlamanın bir parçası olarak geçirmiyordum. 4.194.304 veya 8.388.608 kova boyutları ve kova için hız için bellek içi tablolarda karma dizinler olması gerekir, her ne kadar yüksek boş kova sayıları vermiş olsa da, benim için tatlı nokta gibi görünüyordu.

USE hekatondb
GO

--NB: SQLCMD script, Enable via: Query menu > SQLCMD Mode
:setvar bucketCount 4194304
--:setvar bucketCount 8388608

IF OBJECT_ID('dbo.usp_hekatonFizzBuzz') IS NOT NULL
DROP PROC dbo.usp_hekatonFizzBuzz 
GO
IF OBJECT_ID('dbo.FizzBuzz') IS NOT NULL
DROP TABLE dbo.FizzBuzz
GO


IF OBJECT_ID('dbo.FizzBuzz') IS NULL
CREATE TABLE dbo.FizzBuzz (
    Number      INT NOT NULL,
    Result      VARCHAR(8) NULL,

    CONSTRAINT PK_FizzBuzz PRIMARY KEY NONCLUSTERED HASH ( Number ) WITH ( BUCKET_COUNT = $(bucketCount) )

) WITH ( MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY )
GO


CREATE PROC dbo.usp_hekatonFizzBuzz 

    @limit  INT

WITH
    NATIVE_COMPILATION, 
    SCHEMABINDING, 
    EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH
(
    TRANSACTION ISOLATION LEVEL = SNAPSHOT, 
    LANGUAGE = N'english'
)   

    DECLARE @acc INT = 810092048    -- 11 00 00 01 00 10 01 00 00 01 10 00 01 00 00
    DECLARE @i INT = 1
    DECLARE @c INT

    WHILE @i <= @limit
    BEGIN 

        SELECT
            @c = @acc & 3,
            @acc = ( @acc / 4 ) | ( @c * 268435456 )

        INSERT dbo.FizzBuzz ( Number, Result )
        SELECT @i, SUBSTRING( '       Fizz    Buzz    FizzBuzz', @c * 8, @c * 4 )

        SET @i += 1

    END

END
GO

DELETE dbo.FizzBuzz
DECLARE @startDate DATETIME2 = SYSUTCDATETIME();

EXEC dbo.usp_hekatonFizzBuzz 1000000

SELECT DATEDIFF( millisecond, @startDate, SYSUTCDATETIME() ) diff
GO 10

5

CTE'siz bu tek alt seçimde buldum ve oynadım. Sorgu istatistiklerinde max_elapsed_time 1036

 SELECT num,
        CASE    WHEN mod3 + mod5 = 0 THEN 'FizzBuzz'
                WHEN mod5 = 0 THEN 'Buzz'
                WHEN mod3 = 0 THEN 'Fizz'
                ELSE CONVERT(VARCHAR(8), num)
        END
 FROM 
 (
    SELECT  number as num,
            number % 3 AS mod3,
            number % 5 AS mod5
    FROM    master.dbo.spt_values
    WHERE   name IS NULL
            AND number BETWEEN 1 AND 101
 ) AS numbers;

3

Yazılan kod için kredi almıyorum, sadece ne kadar süreceğini görmek istedim.

BİR MİLYAR SATIR!

;WITH T(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N))
    ,NUMS(N) AS (SELECT TOP(1000000000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))  AS N FROM T T1,T T2,T T3,T T4,T T5,T T6,T T7,T T8,T T9, T T10)
    SELECT  n, ca.fb
    INTO #fizzywizzy
    FROM    NUMS n
            CROSS APPLY ( SELECT    CASE WHEN n.N % 15 = 0 THEN 'FizzBuzz'
                                         WHEN n.N % 3 = 0 THEN 'Fizz'
                                         WHEN n.N % 5 = 0 THEN 'Buzz'
                                         ELSE CAST(n AS VARCHAR)
                                    END AS [fb]
                        ) ca

Cevap: yaklaşık 10 dakika.

SQL Server parse and compile time: 
   CPU time = 13 ms, elapsed time = 13 ms.

 SQL Server Execution Times:
   CPU time = 648625 ms,  elapsed time = 618025 ms.

-2

PostgreSQL

PostgreSQL, generate_seriesbunu büyük ölçüde basitleştiren bir Tablo-Değer Fonksiyonu (Set-Dönen Fonksiyon) sağlar. Sayı ne 3 ne de 5 ne zaman girerse, çıktı almak istemeyeceğinizi farz ediyorum.

SELECT x, str
FROM generate_series(1,49) AS gs(x)
CROSS JOIN LATERAL (VALUES (CASE
  WHEN x % 15 =0 THEN 'Fizzbuzz'
  WHEN x % 3  =0 THEN 'Fizz'
  WHEN x % 5  =0 THEN 'Buzz'
END)) AS c(str)
WHERE str IS NOT NULL;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.