Скорость SQL-запросов - PullRequest
       1

Скорость SQL-запросов

0 голосов
/ 01 декабря 2011

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

select *
from vw_report
where employee_id in (select id from dbo.fnc_security(@personRanAsID))

Функция безопасности запускается менее чем за секунду. Однако, когда я объединяю два, как у меня выше, запрос занимает более 15 минут.

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

Какие-нибудь подсказки или уловки относительно того, где я могу пойти не так?

Возможно, стоит отметить, что когда я копирую результат функции в часть инструкции:

select *
from vw_report
where employee_id in (123, 456, 789)

Скорость увеличивается от 2 до 9 секунд.

Ответы [ 3 ]

2 голосов
/ 01 декабря 2011

Во-первых, здесь поможет любой дополнительный фон ...
- У вас есть код для представления и функции?
- Можете ли вы указать схему и индексы, используемые для таблиц, на которые ссылаются?

Без них совет станет трудным, но у меня будет удар ...

1).Вы можете изменить предложение IN на Join.
2).Вы можете указать WITH (NOEXPAND) в представлении.

SELECT
  *
FROM
  vw_report WITH (NOEXPAND)
INNER JOIN
  (select id from dbo.fnc_security(@personRanAsID)) AS security
    ON security.id = vw_report.employee_id

Примечание: сначала я бы попробовал без NOEXPAND.

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

0 голосов
/ 13 декабря 2011

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

Например:

create table #tempTable (id bigint)

select id 
into #tempTable
from dbo.fnc_security(@personRanAsID)

select *
from vw_report
where id in (select id from #tempTable)
0 голосов
/ 01 декабря 2011

Это занимает так много времени, потому что запрос sub-select выполняется для каждой строки из vw_report, а второй - нет. Вы должны использовать что-то вроде:

select *
from vw_report r, (select id from dbo.fnc_security(@personRanAsID)) v
where r.employee_id = v.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...