Получение N-й самой последней бизнес-даты - очень разная производительность запросов с использованием двух разных методов - PullRequest
2 голосов
/ 14 декабря 2009

У меня есть требование, чтобы получить TXNS на основе T-5. То есть мне нужно «вернуться» на 5 рабочих дней.

Для этого я написал два SQL-запроса, и второй метод работает в 5 раз медленнее, чем первый.

Как получилось?

-- Fast
with
BizDays as
( select top 5 bdate bdate
  from  dbo.business_days 
  where bdate < '20091211'
order by bdate Desc
)
,BizDate as ( select min(bdate) bdate  from BizDays)
select t.* from txns t
join BizDate on t.bdate <= BizDate.bdate

-- Slow
with
BizDays as
( select dense_rank() Over(order by bdate Desc) RN
        , bdate
  from  dbo.business_days 
  where bdate < '20091211'
)
,BizDate as ( select bdate from BizDays where RN = 5)
select t.* from txns t 
join BizDate on t.bdate <= BizDate.bdate

Ответы [ 3 ]

3 голосов
/ 14 декабря 2009

DENSE_RANK не останавливается после первых 5 записей, как TOP 5 делает.

Хотя DENSE_RANK является монотонным и, следовательно, теоретически может быть оптимизировано до TOP WITH TIES, оптимизатор SQL Server не знает об этом и не выполняет эту оптимизацию.

Если ваши рабочие дни уникальны, вы можете заменить DENSE_RANK на ROW_NUMBER и получить ту же производительность, поскольку ROW_NUMBER оптимизирован до TOP.

0 голосов
/ 14 декабря 2009

Причина, по которой это работает так медленно, заключается в том, что DENSE_RANK() и ROW_NUMBER() являются функциями. Движок должен прочитать каждую запись в таблице, которая соответствует предложению WHERE, применить функцию к каждой строке, сохранить значение функции и затем получить первые 5 из этого списка.

«Простая» верхняя 5 использует индекс таблицы, чтобы получить первые 5 записей, которые соответствуют предложению WHERE. В лучшем случае движок может прочитать только пару страниц индекса. В худшем случае, возможно, придется прочитать несколько страниц с данными. Даже без индекса движок читает строки, но не должен выполнять функцию или работать с временными таблицами.

0 голосов
/ 14 декабря 2009

вместо того, чтобы ставить условия в положениях where и join, не могли бы вы, возможно, использовать ORDER BY в данных вашей встречи, а затем LIMIT offset, rowcount?

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