ナンバーズテーブルを作成し、入力するのに最適な方法は何ですか?
質問
数値テーブルを作成し、入力するさまざまな方法を目にしました。 しかし、作成および入力するための最良の方法は何でしょうか? 最良の方法とは、最も重要なものから最も重要でないものへと定義されるものです。
- 最適なインデックス作成で作成されたテーブル
- 最速で生成される行数
- 作成と入力に使用されるシンプルなコード
ナンバーズ・テーブルが何であるか分からない場合は、ここを見てください。 なぜ補助数表の使用を検討する必要があるのですか?
どのように解決するのですか?
ウェブやこの質問に対する回答から抜粋したコード例です。
各メソッドについて、私はそれぞれが同じテーブルと列を使用するように元のコードを変更しました。NumbersTest と Number で、10,000 行またはそれにできるだけ近いものを使用します。 また、元の場所へのリンクを提供しました。
メソッド1
からの非常に遅いループメソッドです。
ここで
平均13.01秒
3回の走行で最高値を更新、以下は秒単位でのタイムです。12.42, 13.60
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
CREATE TABLE NumbersTest(Number INT IDENTITY(1,1))
SET NOCOUNT ON
WHILE COALESCE(SCOPE_IDENTITY(), 0) < 100000
BEGIN
INSERT dbo.NumbersTest DEFAULT VALUES
END
SET NOCOUNT OFF
-- Add a primary key/clustered index to the numbers table
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE())/1000.0)+' seconds'
SELECT COUNT(*) FROM NumbersTest
メソッド2
より高速なループ処理です。
ここで
平均 1.1658 秒
は、最高を削除11回実行し、ここで秒単位で時間を示します。1.117, 1.140, 1.203, 1.170, 1.173, 1.156, 1.203, 1.153, 1.173, 1.170
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
CREATE TABLE NumbersTest (Number INT NOT NULL);
DECLARE @i INT;
SELECT @i = 1;
SET NOCOUNT ON
WHILE @i <= 10000
BEGIN
INSERT INTO dbo.NumbersTest(Number) VALUES (@i);
SELECT @i = @i + 1;
END;
SET NOCOUNT OFF
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE())/1000.0)+' seconds'
SELECT COUNT(*) FROM NumbersTest
メソッド3
以下は、以下のコードに基づく単一の INSERT です。
ここに
平均 488.6 ミリ秒
11回実行し、最高を削除し、ここにミリ秒単位で時間を示します。686, 673, 623, 686,343,343,376,360,343,453
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
CREATE TABLE NumbersTest (Number int not null)
;WITH Nums(Number) AS
(SELECT 1 AS Number
UNION ALL
SELECT Number+1 FROM Nums where Number<10000
)
insert into NumbersTest(Number)
select Number from Nums option(maxrecursion 10000)
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
SELECT COUNT(*) FROM NumbersTest
メソッド4
の半ループのメソッドです。
ここで
平均 348.3 ミリ秒 (コードの途中に "GO" があるため、良いタイミングを得るのが困難でした。何か提案があればお願いします)
は11回実行し、最高を削除し、ここにミリ秒単位で時間を示します。 356, 360, 283, 346, 360, 376, 326, 373, 330, 373
DROP TABLE NumbersTest
DROP TABLE #RunDate
CREATE TABLE #RunDate (RunDate datetime)
INSERT INTO #RunDate VALUES(GETDATE())
CREATE TABLE NumbersTest (Number int NOT NULL);
INSERT NumbersTest values (1);
GO --required
INSERT NumbersTest SELECT Number + (SELECT COUNT(*) FROM NumbersTest) FROM NumbersTest
GO 14 --will create 16384 total rows
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
SELECT CONVERT(varchar(20),datediff(ms,RunDate,GETDATE()))+' milliseconds' FROM #RunDate
SELECT COUNT(*) FROM NumbersTest
メソッド5
からのシングルINSERTです。
フィリップ・ケリー氏の回答
平均92.7ミリ秒
11回実行し、最高を削除し、ここにミリ秒単位で時間を示します。80, 96, 96, 93, 110, 110, 80, 76, 93, 93
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
CREATE TABLE NumbersTest (Number int not null)
;WITH
Pass0 as (select 1 as C union all select 1), --2 rows
Pass1 as (select 1 as C from Pass0 as A, Pass0 as B),--4 rows
Pass2 as (select 1 as C from Pass1 as A, Pass1 as B),--16 rows
Pass3 as (select 1 as C from Pass2 as A, Pass2 as B),--256 rows
Pass4 as (select 1 as C from Pass3 as A, Pass3 as B),--65536 rows
--I removed Pass5, since I'm only populating the Numbers table to 10,000
Tally as (select row_number() over(order by C) as Number from Pass4)
INSERT NumbersTest
(Number)
SELECT Number
FROM Tally
WHERE Number <= 10000
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
SELECT COUNT(*) FROM NumbersTest
メソッド6
からのシングルINSERTです。
Mladen Prajdic さんの回答
平均 82.3 ミリ秒
11回実行し、最高を削除し、ここでミリ秒単位で時間を示します。80, 80, 93, 76, 93, 63, 93, 76, 93, 76
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
CREATE TABLE NumbersTest (Number int not null)
INSERT INTO NumbersTest(Number)
SELECT TOP 10000 row_number() over(order by t1.number) as N
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number);
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
SELECT COUNT(*) FROM NumbersTest
メソッド7
のコードに基づく単一のINSERTです。
ここに
平均56.3ミリ秒
は、最高を削除11回走った、ここではミリ秒単位で時間を示します。63, 50, 63, 46, 60, 63, 63, 46, 63, 46
DROP TABLE NumbersTest
DECLARE @RunDate datetime
SET @RunDate=GETDATE()
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO NumbersTest
FROM sys.objects s1 --use sys.columns if you don't get enough rows returned to generate all the numbers you need
CROSS JOIN sys.objects s2 --use sys.columns if you don't get enough rows returned to generate all the numbers you need
ALTER TABLE NumbersTest ADD CONSTRAINT PK_NumbersTest PRIMARY KEY CLUSTERED (Number)
PRINT CONVERT(varchar(20),datediff(ms,@RunDate,GETDATE()))+' milliseconds'
SELECT COUNT(*) FROM NumbersTest
これらの方法をすべて見た後、私は方法7が最も速く、コードもかなり単純で、とても気に入っています。
関連
-
[解決済み】SQL Server データベース復元エラー:指定されたキャストは有効ではありません。(SqlManagerUI)
-
[解決済み] SQLでNaN値をNULLに、またはNaNを0に変換する
-
[解決済み] SQL ServerでGROUP BYと一緒にDISTINCTを使用する
-
[解決済み] varcharとnvarcharの違いは何ですか?
-
[解決済み] SQL Server - 挿入された行のIDを取得するための最良の方法は?
-
[解決済み] クラスター化インデックスと非クラスター化インデックスの実際の意味は何ですか?
-
[解決済み] SQL Serverにおけるchar、nchar、varchar、nvarcharの違いは何ですか?
-
[解決済み] SQL Serverで結果をページ分割する最も良い方法は何ですか?
-
[解決済み】Integrated Security = True と Integrated Security = SSPI の違いは何ですか?
-
[解決済み】データベースで継承を表現するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] SQL Server MS 2012の現在のセキュリティコンテキストでは、サーバープリンシパルはデータベースにアクセスできません。
-
[解決済み] データベース 'tempdb' で CREATE TABLE 権限が拒否されました。
-
[解決済み] リンクサーバーとしてローカルデータベースを使用する場合、「Deferred prepare could not be completed」エラーが発生する。
-
[解決済み] 変数に値を代入するSELECT文は、データ検索操作と組み合わせてはいけません。
-
[解決済み] EF: テキストデータ型は比較できないため、DISTINCT として選択できません。
-
[解決済み] create関数は、バッチ内の唯一のステートメントでなければなりません。
-
[解決済み] NVARCHAR(MAX)の最大文字数を教えてください。[重複しています]。
-
[解決済み] SQL Server の .sql ファイルとは何ですか?
-
[解決済み] 条件付きJOINステートメント SQL Server
-
[解決済み] 日付から年内の週番号を取得する