2017-08-15 8 views
3

次のスクリプトを使用して、AAA-0000からZZZ-0000までの範囲の 'ABC-1234'形式のユニークな英数字コード175万個(! 9999。AlphaNumericコードの大きなテーブルを作成するSQLスクリプトを高速化するには

私の専用MS SQL 2016ボックスでこのスクリプトをそのまま実行すると、20時間かかります。これをスピードアップする最善の方法は何ですか?スクリプトからわかるように、私のSQLスキルはいくぶん欠けています!

ID(int)列、ID、およびCODE(nvarchar(20))自体の列があります。

CREATE TABLE [dbo].[ORDERED_CODES](
[ID] [int] NOT NULL, 
[Code] [nvarchar](20) NOT NULL, 
CONSTRAINT [PK_ORDERED_CODES] PRIMARY KEY CLUSTERED 
(
[ID] ASC, 
[Code] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,     
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

スクリプト:

DECLARE @Alpha1 INT; 
DECLARE @Alpha2 INT; 
DECLARE @Alpha3 INT; 
DECLARE @Num INT; 

-- alpha elements 'ABC' 
SET @Alpha1 = 65; 
SET @Alpha2 = 65; 
SET @Alpha3 = 65; 

-- number element '9999' 
SET @Num = 0; 

-- temporary holders 
DECLARE @FINALCODE Nvarchar(50); 
DECLARE @CODE1 Nvarchar(50); 
DECLARE @CODE2 Nvarchar(50); 
DECLARE @CODE3 Nvarchar(50); 

WHILE @Alpha1 < 91 
BEGIN 
    SET @CODE1 = CHAR(@Alpha1) 
     WHILE @Alpha2 < 91 
     BEGIN 
     SET @CODE2 = @CODE1 + CHAR(@Alpha2) 
     SET @Alpha2 = @Alpha2 +1 
      WHILE @Alpha3 < 91 
       BEGIN 
        SET @CODE3 = @CODE2 + CHAR(@Alpha3) 
        SET @Alpha3 = @Alpha3 +1 
         WHILE @Num < 10000 
          BEGIN 
           SET @FINALCODE = RIGHT('0000'+ CAST(@Num as nvarchar(4)),4) + CHAR(45) + @CODE3   
           SET @Num = @Num +1 
           INSERT INTO ORDERED_CODES (CODE) VALUES (@FINALCODE) 
          END 
         SET @FINALCODE = null 
         SET @Num = 0 
       END 
      SET @Alpha3 = 65 
    END 
    SET @Alpha2 = 65 

    SET @Alpha1 = @Alpha1 +1 
END; 

任意およびすべての思考がありがたく感謝している2つの列が主キーを構成します!

+0

ゴードン、ダン&ジョンの助けを借りてくれてありがとう、すべて同じテーマですばらしい答えですので、悲しいことに私は答えとして1つを選択しなければならない...そう最高のSOの伝統ではゴードンに行く必要があります最初になるために。言うまでもなく、私はCTEを読み上げるつもりです!私のサーバでは4分ほどでDanのものが最も速かったです。私の太ったサーバーがデスクトップより5倍遅い理由を試してみる必要があります。 20時間をはるかに上回り、とても感謝しています。乾杯! –

答えて

1

私だけだろう:

with alphas as (
     select v.ch 
     from (values ('A'), ('B'), . . . 
      ) v(ch) 
    ), 
    digits as (
     select v.ch 
     from values ('0'), ('1'), . . . 
    ) 
select (a1.ch + a2.ch + a3.ch + d1.ch + d2.ch + d3.ch + d4.ch) as code 
from alphas a1 cross join 
    alphas a2 cross join 
    alphas a3 cross join 
    digits d1 cross join 
    digits d2 cross join 
    digits d3 cross join 
    digits d4; 

. . .は、あなたがしたい有効な文字です。必要に応じて、values以外の方法を使用して値を生成することができます。

1

アドホック集計テーブルの助けを借りて。 1分で175,760,000件のレコードが6.799秒(私のラップトップ上)。最終的な結果は

enter image description here

のように見え99999

- Z

CTEN 0000を生成します - または、37.833秒Order By

;with cteC as (
    Select Top 26 C=char(64+Row_Number() Over (Order By (Select NULL))) From master..spt_values n1 
), cteN as (
Select Top 10000 N= right(concat('0000',Row_Number() Over (Order By (Select NULL))-1),4) From master..spt_values n1, master..spt_values n2 
) 
Insert Into Ordered_Codes (Code) 
Select Code=Concat(A.C,B.C,C.C,'-',N.N) 
From cteC A,cteC B,cteC C,cteN N 
Order By 1 

なしCTECを生成します

1

私はCTEクエリがループよりもはるかに良好に動作することを期待:

WITH 
    alpha_values AS (
     SELECT value FROM(VALUES 
      ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M') 
      ,('N'),('O'),('P'),('Q'),('R'),('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z')) 
      AS alpha_values(value) 
    ) 
    ,t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n)) 
    ,number_values AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1 AS value FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c) 
INSERT INTO dbo.ORDERED_CODES (Code) 
SELECT 

     alpha_values1.value 
    + alpha_values2.value 
    + alpha_values3.value 
    + '-' 
    + RIGHT('000' + CAST(number_values.value AS varchar(4)), 4) 
    AS Code 
FROM alpha_values AS alpha_values1 
CROSS JOIN alpha_values AS alpha_values2 
CROSS JOIN alpha_values AS alpha_values3 
CROSS JOIN number_values 
ORDER BY Code; 

私が掲示した後まで、ゴードンの同様のソリューションを見ていない EDIT。上記のクエリは、デスクトップ上で35秒で実行されました。

関連する問題