Эффективная фильтрация данных в табличном параметре в хранимой процедуре - PullRequest
0 голосов
/ 20 марта 2012

У меня есть табличный тип в качестве параметра для хранимой процедуры, в котором может быть что угодно, вплоть до тысяч строк. Я выполняю несколько операций над этой хранимой процедурой (в настоящее время MERGE и INSERT), но перед ними я хочу отфильтровать содержимое параметра в предикате:

@data TableValuedType READONLY

MERGE INTO Table2
USING (
    SELECT ... FROM @data
    UNION
    SELECT ... FROM @data
    UNION
    ...)
ON ...
WHEN NOT MATCHED THEN ....

INSERT INTO Table3
    SELECT ... FROM @data

Наиболее эффективный способ сделать это, чтобы объявить другую переменную типа таблицы, вставить в нее, а затем использовать эту переменную для объединения и вставки из:

DECLARE @sanitisedData TableValuedType
INSERT INTO @sanitisedData
    SELECT ... FROM @data
    WHERE <predicate>

или использовать предикат каждый раз, когда я выбираю что-то из @data:

MERGE INTO Table2
USING (
    SELECT ... FROM @data WHERE <predicate>
    UNION
    SELECT ... FROM @data WHERE <predicate>
    UNION
    ...)
ON ...
WHEN NOT MATCHED THEN ....

INSERT INTO Table3
    SELECT ... FROM @data WHERE <predicate>

или что-то еще?

1 Ответ

0 голосов
/ 29 марта 2012

Избегайте использования переменной @Table, когда это возможно. Это, в большинстве случаев, приведет к снижению производительности. Вместо этого выберите временную таблицу.

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

Поэтому я предлагаю вам использовать временную таблицу и создать индекс для столбцов, по которым вы фильтруете.

Надеюсь, это поможет.

...