Как я могу ускорить запрос T-SQL - PullRequest
1 голос
/ 10 августа 2009

Я разработал несколько хранимых процедур T-SQL, которые перебирают значительную часть данных. Первый занимает пару минут, чтобы обработать данные за год, что хорошо для моих целей. Второй, который использует ту же структуру / алгоритм, хотя и с большим количеством данных, занимает два часа, что невыносимо.

Я использую SQL-сервер и Query-Analyzer. Существуют ли какие-либо инструменты профилирования, и если да, то как они работают?

В качестве альтернативы, есть мысли о том, как улучшить скорость, основываясь на псевдокоде ниже? Короче говоря, я использую курсор для перебора данных из прямого SELECT (из нескольких соединенных таблиц). Затем я строю инструкцию INSERT на основе значений и вставляю результат в другую таблицу. Некоторые из переменных SELECT требуют небольшой манипуляции перед INSERTion. Включает извлечение некоторых частей даты из значения даты, некоторые базовые операции с плавающей запятой и некоторую конкатенацию строк.

--- Грубый алгоритм / псевдокод

DECLARE <necessary variables>
DECLARE @cmd varchar(1000)
DECLARE @insert varchar(100) = 'INSERT INTO MyTable COL1, COL2, ... COLN, VALUES('

DECLARE MyCursor Cursor FOR
    SELECT <columns> FROM TABLE_1 t1
    INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
    INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey

OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @VAL1, @VAL2, ..., @VALn
WHILE @@FETCH_STATUS = 0
BEGIN
   @F = @VAL2 / 1.1  --- float op
   @S = @VAL3 + ' ' + @VAL1
   SET @cmd = @insert
   SET @cmd = @cmd + DATEPART(@VAL1) + ', '
   SET @cmd = @cmd + STR(@F) + ', '
   SET @cmd = @cmd + @S + ', '
   SET @cmd = @cmd + ')'
   EXEC (@cmd)
   FETCH NEXT FROM MyCursor @VAL1, @VAL2, ..., @VALn
END
CLOSE MyCursor
DEALLOCATE MyCursor

Ответы [ 5 ]

11 голосов
/ 10 августа 2009

Первое, что нужно сделать - избавиться от курсора ...

INSERT INTO MyTable COL1, COL2, ... , COLN
SELECT ...cols and manipulations...
FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey

Большинство вещей должно быть возможно напрямую в TSQL (это трудно определить без примера) - и вы могли бы рассмотреть UDF для более сложных операций.

5 голосов
/ 10 августа 2009

потерять курсор. Сейчас. (См. Здесь, почему: Почему использование курсоров в SQL Server считается плохой практикой? ).

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

Если то, что вы делаете, сложно, и вы не уверены, я бы сделал это в три этапа:

1) Выбор основных данных во временную таблицу с помощью вставки или выбора в.

2) Используйте update для выполнения манипуляций - вы можете сделать это, просто обновляя существующие столбцы, или вам может понадобиться добавить несколько дополнительных в правильном формате при создании временной таблицы. Вы можете использовать несколько операторов обновления, чтобы разбить его дальше, если хотите.

3) Выберите его там, где вы хотите.

Если вы хотите вызвать все это как один шаг, то вы можете затем обернуть все это в хранимую процедуру.

Это облегчает отладку и облегчает работу с кем-то еще, если это необходимо. Вы можете разбить свои обновления на отдельные шаги, чтобы вы могли быстро определить, что пошло не так, где.

Это говорит о том, что я не верю, что то, что вы делаете, не может быть сделано с помощью одного оператора вставки. Это может быть не привлекательно, но я верю, что это можно сделать:

INSERT INTO NewTable
DATEPART(@VAL1) DateCol, 
@STR(@VAL2 / 1.1) FloatCol,
@VAL3 + ' ' + @VAL1 ConcatCol
FROM TABLE_1 t1
INNER JOIN TABLE_2 t2 on t1.key = t2.foreignKey
INNER JOIN TABLE_3 t3 on t2.key = t3.foreignKey

DateCol, FloatCol и ConcatCol - это любые имена, которые вы хотите иметь в столбцах. Хотя они не нужны, лучше всего назначить их следующим образом: (а) это делает более понятным то, что вы делаете, и (б) некоторые языки борются с безымянными столбцами (и обрабатывают это очень неясным образом).

0 голосов
/ 10 августа 2009

SQl Server также поставляется с инструментом профилирования, который называется SQL Server Profiler. Это первый выбор в меню «Инструменты» в SSMS.

0 голосов
/ 10 августа 2009

Есть ли инструменты профилирования, и, если Итак, как они работают?

Чтобы ответить на ваш вопрос об инструментах настройки запросов, вы можете использовать TOAD для SQL Server, чтобы помочь в настройке запросов.

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

Что еще более важно, я использовал его, чтобы стать лучшим автором t-sql, поскольку я использую советы по будущим сценариям, которые я пишу. Я не знаю, как TOAD будет работать с этим скриптом, потому что, как уже упоминали другие, он использует курсор, и я не использую их, поэтому никогда не пытался оптимизировать его.

TOAD - это огромный инструментарий функциональности SQL Server, и оптимизация запросов - это только малая часть. Кстати, я никак не связан с Quest Software.

0 голосов
/ 10 августа 2009

избавиться от курсора и динамического sql:

INSERT INTO MyTable 
        (COL1, COL2, ... COLN)
    SELECT 
        <columns>
            ,DATEPART(@VAL1) AS DateCol
            ,@STR(@VAL2 / 1.1) AS FloatCol
            ,@VAL3 + ' ' + @VAL1 AS ConcatCol
        FROM TABLE_1        t1    
        INNER JOIN TABLE_2  t2 on t1.key = t2.foreignKey
        INNER JOIN TABLE_3  t3 on t2.key = t3.foreignKey
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...