Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Apa cara terbaik untuk membuat dan mengisi tabel angka?

berikut adalah beberapa contoh kode yang diambil dari web dan dari jawaban atas pertanyaan ini.

Untuk Setiap Metode, saya telah memodifikasi kode asli sehingga masing-masing menggunakan tabel dan kolom yang sama:NumbersTest dan Number, dengan 10.000 baris atau sedekat mungkin dengan itu. Juga, saya telah memberikan tautan ke tempat asal.

METODE 1 di sini adalah metode perulangan yang sangat lambat dari sini
rata-rata 13,01 detik
berlari 3 kali dihapus tertinggi, berikut adalah waktu dalam detik: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

METODE 2 di sini adalah perulangan yang jauh lebih cepat dari sini
rata-rata 1,1658 detik
berlari 11 kali dihapus tertinggi, berikut adalah waktu dalam detik: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

METODE 3 Berikut ini adalah INSERT tunggal berdasarkan kode dari sini
rata-rata 488.6 milidetik
berlari 11 kali terhapus tertinggi, berikut adalah waktu dalam milidetik: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

METODE 4 di sini adalah metode "semi-loop" dari sini rata-rata 348,3 milidetik (sulit untuk mendapatkan waktu yang tepat karena "GO" di tengah kode, saran apa pun akan dihargai)
berlari 11 kali dihapus tertinggi, berikut adalah waktu dalam milidetik: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

METODE 5 di sini adalah satu INSERT dari jawaban Philip Kelley
rata-rata 92,7 milidetik
berlari 11 kali dihapus tertinggi, berikut adalah waktu dalam milidetik: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

METODE 6 di sini adalah satu INSERT dari Mladen Prajdic jawaban
rata-rata 82,3 milidetik
berlari 11 kali dihapus tertinggi, berikut adalah waktu dalam milidetik: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

METODE 7 di sini adalah INSERT tunggal berdasarkan kode dari sini
rata-rata 56,3 milidetik
berlari 11 kali dihapus tertinggi, berikut adalah waktu dalam milidetik: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

Setelah melihat semua metode ini, saya sangat menyukai Metode 7, yang tercepat dan kodenya juga cukup sederhana.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dapatkan Nama Kolom dari ID-nya di SQL Server:COL_NAME()

  2. SQL Server - gabung dalam saat memperbarui

  3. Bagaimana saya bisa memasukkan 10 juta catatan dalam waktu sesingkat mungkin?

  4. Bandingkan DATETIME dan DATE dengan mengabaikan porsi waktu

  5. Cara menambahkan Batasan kunci Asing ke tabel yang ada di SQL Server - Tutorial SQL Server / TSQL Bagian 68