2016-01-07 4 views
0

Я работаю над созданием Лаборатории с большой базой данных MSSQL. Чтобы упростить эту проблему, предположим, что это только для 1 таблицы (если я могу найти лучшее решение, я могу сделать это для всех таблиц)TSQL - записи клонов за день

У меня есть данные за 1 день в таблице, скажем между 525 и 630k записей. Я хочу дублировать данные для разных дней (создать историю).

Я уже пробовал разные способы, и я нахожу это очень долго. изначально процесс забирал 91 час, чтобы дублировать 1 день ... Я перенес его на 16 минут, чтобы обработать 1 день (что составляет около 91 часа, чтобы дублировать год). Мне интересно, есть ли какой-нибудь инструмент или что-то сделанное для дублирования данных или создания истории быстро?

Вот что я прямо сейчас:

Declare @iDateCnt int=1, 
      @TmpDate datetime, 
      @iDate int=365, -- counter to create a years worth of history. 
      @DateStart datetime = '2015-12-22' 
    Select F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, getdate() as F11 
    into #TMP_Table1 
    From Table1 where F1 = @DateStart -- Template Day to be duplicated 

While @iDateCnt<[email protected] 
Begin 
    Set @TmpDate = @[email protected] 
    Delete from Table1 where F1 = @TmpDate 
    Insert into Table1 (F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11) 
     Select @TmpDate as F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, getdate() as F11 
     from #Tmp_Table1 

    Drop #Tmp_Table1 
End 
+0

Причина, по которой это так медленно, вы делаете по одной записи за раз в цикле. SQL не может иметь никакого шанса оптимизировать это, он (скорее всего) будет работать в секундах как пакет. – Jamiec

+1

Создайте таблицу дат (или CTE), которая содержит одну строку для каждой даты, которую вы хотите заполнить, а затем перейдите в эту таблицу вместо того, чтобы запускать цикл. –

+0

Почему вы используете цикл while для этого? В этом суть проблемы производительности. Это можно переписать в виде вставки, основанной на одном наборе. –

ответ

1

Для того чтобы сформулировать мой комментарий в ответ, вы должны начать с создания таблицы, которая имеет столбец DATETIME, с одной строкой для каждой даты, которую вы хотите заполнить клонированными данными. Скажем, мы называем это tblDates. Тогда вы бы просто сделать это в существующий сценарий:

Select F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, getdate() as F11 
into #TMP_Table1 
From Table1 where F1 = @DateStart -- Template Day to be duplicated 

    Insert into Table1 (F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11) 
     Select tblDates.DtColumn as F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, getdate() as F11 
     from #Tmp_Table1 
     CROSSJOIN tblDates 

    Drop #Tmp_Table1 
End 

Это создаст копию всех данных в #TMP_Table1 для каждой строки в tblDates, с датой от tblDates в F1 колонке (где вы были ранее с помощью переменная цикла).

+0

На основании вашего комментария Это именно то, что я закончил делать. Спасибо. – JohnG

+0

результат дублирования записей за целый год: из дискового пространства и всего висело.Поскольку мой тест на 1 день занял 25 секунд, я ожидаю, что он займет до 3 часов в течение всего года, но из-за размера набора данных я сомневаюсь, что это будет работать лучше. У меня такое чувство, что мне нужно будет зацикливаться и делать куски за раз, но с большим объемом дискового пространства, я подожду и посмотрю, как работает полгода. – JohnG

+0

Вероятно, вы получите более высокую производительность, зацикливая это решение и разбив его на куски. Создание 365 копий строк 600 тыс. ... это займет некоторое время. :) –

1

Делая один вкладыш в то время всегда будет медленным, особенно с сильно индексированной таблицы.

Вместо этого вы должны сделать это в качестве одной вставки, что-то вдоль линий

DECLARE @startDate DATETIME = '2015-12-22' 
DECLARE @endDate = DATEADD(days,365, @startDate) 

Insert into Table1 (F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11)   
Select F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, getdate() 
FROM Table1 where F1 > @startDate AND F1 <= @endDate 
+0

@Tmpdate - это дата, когда я зацикливаюсь. Я не вижу здесь разницы. – JohnG

+0

@JohnG - извините, левый '@ tmpdata' случайно. его простой выбор из исходной вставки в пункт назначения (та же таблица в вашем случае) – Jamiec

+0

, но это не сработает, так как мне нужно менять F1 каждый день в году. мой шаблон в таблице имеет 525K записей с датой 2015-12-22; Мне нужно скопировать этот набор данных за каждый другой день этого года ... Итак, F1 принимает значение за каждый день. Я думаю, что ответ Tab Alleman с использованием перекрестного соединения является правильным. все, что вам не хватает в вашем решении, - это добавить таблицу дат, скрестить ее и использовать эту дату как F1. – JohnG

Смежные вопросы