Более быстрая альтернатива использованию курсора в SQL Server - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть курсор, который перебирает каждую базовую таблицу в базе данных.Он вставляет записи в другую таблицу, выполняя фрагмент динамического SQL, но на данный момент выполнение занимает более 20 минут.

DECLARE TableCursor CURSOR FOR
    SELECT TABLE_NAME
    FROM <DB>.INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'BASE TABLE'

WHILE(@@FETCH_STATUS = 0)
BEGIN
    #Dynamic SQL Query to insert data into each table in cursor#

Я провел некоторое исследование и обнаружил, что с помощью CTE с выражением UNIONбудет намного быстрее, но я не уверен, как выполнить преобразование, например, как циклически проходить по каждой таблице в CTE.

Любая помощь очень ценится.

РЕДАКТИРОВАТЬ : это пример динамического SQL:

SELECT @SQL = 'WITH CTE_DATES(DATE_VAL) AS (
    SELECT DISTINCT DATE_VAL
    FROM DATE_EVERY_DAY
    WHERE DATE_VAL <= GETDATE()
)
INSERT INTO COUNT_RECORDS_TABLE (DATE_VAL, TABLE_NAME, NUM_RECS_IMPORTED)
SELECT cd.DATE_VAL, ''' + @TableName + ''' AS TABLE_NAME, COUNT(CAST(tn.IMPORT_DATE AS DATE)) AS NUM_RECS_IMPORTED
FROM CTE_DATES AS cd LEFT JOIN ' + @TableName + ' AS tn 
ON CAST(tn.IMPORT_DATE AS DATE) = cd.DATE_VAL
GROUP BY cd.DATE_VAL'

1 Ответ

1 голос
/ 02 апреля 2019

Я бы попробовал использовать sys.sp_MSForeachTable. Это примерно так быстро, как это получается, а? символ - это имя таблицы в формате [схема]. [имя таблицы]. Очевидно, что вы можете немного заменить текст, если вам просто нужно имя таблицы. Прямая замена означает, что вам не нужно связываться с CTE, и если в столбце DATE_EVERY_DAY.DATE_VAL есть индекс, возможно, этот запрос сможет его использовать.

EXEC sys.sp_MSforeachtable 
'INSERT INTO COUNT_RECORDS_TABLE (DATE_VAL, TABLE_NAME, NUM_RECS_IMPORED)
SELECT 
    cd.DATE_VAL,
    ''?'' AS TABLE_NAME, 
    COUNT(tn.IMPORT_DATE) AS NUM_RECS_IMPORTED 
FROM 
    DATE_EVERY_DAY AS cd
    LEFT JOIN 
    ? AS tn ON 
        CAST(tn.IMPORT_DATE AS DATE)=cd.DATE_VAL
WHERE
    DATE_VAL <= GETDATE()
GROUP BY
    cd.DATE_VAL
'

Здесь приведен более подробный пример: Недокументированные хранимые процедуры SQL Server sp_MSforeachtable и sp_MSforeachdb

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...