2013-04-30 2 views
1

Я пытаюсь вставить 100 000 000 простых записей с координатами в таблицу. Есть ли более быстрый способ сделать это произойдет, чем команда T-SQL нижеСамый быстрый способ создания и заполнения таблицы набором значений (x, y)

declare @x int 
declare @y int 
set @x = 0 
set @y = 0 

begin tran 
while @x < 10000 
begin 
    while @y < 10000 
    begin 
     insert into world (x,y) VALUES (@x,@y) 
     set @y = @y + 1 
    end 
    set @y = 0 
    set @x = @x + 1 
end 
commit tran 
+2

У Вас есть те координаты, доступные во внешнем файле? Вы можете загрузить его в промежуточную таблицу .... –

+0

Я не знаю, но я подозреваю, что создание файла займет столько же времени, сколько и выше. Время экспериментировать. – mxmissile

+0

Вместо 100 000 000 индивидуальных INSERT вам, вероятно, будет лучше с синтаксисом INSERT INTO SELECT или синтаксисом SELECT INTO. Из них я бы предположил, что SELECT INTO может работать лучше. См. Здесь [здесь] (http://www.blackwasp.co.uk/SQLSelectInsert.aspx), например. – mbeckish

ответ

2

Нечто подобное могло бы работать, если 100 строк мельничные не слишком большой глоток для сервера, чтобы сделать в одной части - это, очевидно, зависит от размера и скорости вашего лог-файла.

WITH counter AS 
(SELECT TOP 10000 ROW_NUMBER() 
    OVER (ORDER BY a.[object_id], a.name, b.[object_id]) AS rownum 
    FROM sys.columns a, sys.columns b) 
INSERT INTO World (x,y) 
SELECT a.rownum, b.rownum 
    FROM counter a, counter b 
3

Если у вас есть стол с цифрами, пожалуйста, используйте свою собственную таблицу номеров. В противном случае вы можете использовать spt_values, как показано ниже.

WITH base_num AS 
(SELECT number FROM master..spt_values WHERE type = 'P' AND number < 100) 
, num AS 
(SELECT b1.number * 100 + b2.number AS number 
FROM base_num b1 
CROSS JOIN base_num b2 
) 
INSERT INTO world (x,y) 
SELECT n1.number AS x, n2.number AS y 
FROM num n1 
CROSS JOIN num n2 
+0

spt_values ​​недокументирован и может дать неожиданные результаты. В этом случае он может не производить достаточно для создания требуемых записей. – StingyJack

+0

@StingyJack, как я уже упоминал в своем ответе, если у ОП есть собственная таблица чисел, то следует использовать его. Кроме того, не могли бы вы привести пример, что «spt_values ​​может дать неожиданные результаты». Мне было бы интересно узнать это. – EricZ

+0

Считается «внутренним» и, следовательно, не документировано. Если документации нет, вы выписываете поведение, и оно может сделать что-то неожиданное. http://stackoverflow.com/a/4280038/16391 – StingyJack

2

Вы можете использовать таблицу чисел

SELECT TOP 10000 -- use a smaller value for testing, this will take a bit 
     IDENTITY(INT,1,1) as N 
    INTO #Numbers 
    FROM Master.dbo.SysColumns sc1, 
     Master.dbo.SysColumns sc2 

Тогда что-то вроде

SELECT 
    n1.N as 'N1' 
    , n2.N as 'N2' 
INTO #values 
FROM #Numbers n1 
    CROSS JOIN #Numbers n2 


SELECT COUNT(*) FROM #values 

Чтобы получить декартово множеств, при условии, вы можете использовать упрощенные значения координат.

+1

Потребовалось около 12 секунд, чтобы создать миллион номеров. Я использую только общий VM SQL Server, поэтому я не осмеливаюсь попробовать 100MM. – StingyJack

2

Если вы не имеете таблицу чисел, вы можете моделировать один с КТР:

with cte as 
(select 1 i union all select i+1 i from cte where i < 10000) 
INSERT into World (x,y) 
SELECT x.i, y.i 
from cte x cross join cte y 
option (maxrecursion 0)