Настройка производительности на оператор ORDER BY с фильтром для одного результата - PullRequest
0 голосов
/ 09 апреля 2020

У меня следующий простой запрос:

SELECT TOP 1 message 
FROM Log l 
WHERE l.id_fk = '##Guid##'
AND l.id_category IN ('Category 1', 'Category 2') 
ORDER BY l.timestamp DESC

Время выполнения для больших таблиц журнала без некластеризованного нисходящего индекса на timestamp очень велико, потому что сначала нужно получить полный список, чтобы получить top 1 запись.

Можно ли избавиться от заказа с помощью оператора или создание индекса полностью лучшее решение?

Ответы [ 3 ]

1 голос
/ 09 апреля 2020

Я думаю, что самый быстрый подход - это более сложный запрос:

SELECT TOP (1) message
FROM ((SELECT TOP 1 l.message, l.timestamp
       FROM Log l 
       WHERE l.id_fk = '##Guid##' AND
             l.id_category = 'Category 1'
       ORDER BY l.timestamp DESC
      ) UNION ALL
      (SELECT TOP 1 l.message, l.timestamp
       FROM Log l 
       WHERE l.id_fk = '##Guid##' AND
             l.id_category = 'Category 2'
       ORDER BY l.timestamp DESC
      ) 
     ) l
ORDER BY timestamp DESC

Это может использовать индекс на log(id_fk, id_category, l.timestamp). К сожалению, SQL не может использовать индекс на timestamp с IN.

0 голосов
/ 09 апреля 2020

Запрос в порядке. Вы хотите этот индекс:

 CREATE INDEX idx ON log (id_fk, id_category, timestamp DESC);

Или даже это:

 CREATE INDEX idx ON log (id_fk, id_category, timestamp DESC, message);

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

0 голосов
/ 09 апреля 2020

Попробуйте это:

SELECT TOP 1 message 
FROM (select l.timestamp,l.message
        FROM Log l 
        WHERE l.id_fk = '##Guid##'
        AND l.id_category IN ('Category 1', 'Category 2') 
        ) x
ORDER BY x.timestamp DESC

Просто списав верхнюю часть головы, в основном внутренний запрос фильтрует ваши условия данных в меньший набор, а затем приказывает получить верхнюю 1

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