Нижеприведенный запрос обращается к таблице голосов, содержащей более 30 миллионов строк. Затем набор результатов выбирается из WHERE n = 1
. В плане запроса операция SORT в оконной функции ROW_NUMBER() составляет 95% от стоимости запроса, и для завершения выполнения требуется более 6 минут.ROW_NUMBER() Query Plan SORT Optimization
У меня уже есть индекс на same_voter, eid, country include vid, nid, sid, vote, time_stamp, new
, чтобы покрыть предложение where.
Самый эффективный способ исправить это, чтобы добавить индекс на vid, nid, sid, new DESC, time_stamp DESC
или есть ли альтернатива использованию функции ROW_NUMBER() для достижения таких же результатов более эффективным образом?
SELECT v.vid, v.nid, v.sid, v.vote, v.time_stamp, v.new, v.eid,
ROW_NUMBER() OVER (
PARTITION BY v.vid, v.nid, v.sid ORDER BY v.new DESC, v.time_stamp DESC) AS n
FROM dbo.Votes v
WHERE v.same_voter <> 1
AND v.eid <= @EId
AND v.eid > (@EId - 5)
AND v.country = @Country
95% для операции не так важно, вам нужно посмотреть на весь запрос. Это очень медленно? Единственное, что я вижу, это проблемы с параметрами нюхания, так как у вас есть 2 параметра. Индекс: fine.https://www.brentozar.com/archive/2013/06/the-elephant-and-the-mouse-or-parameter-sniffing-in-sql-server/ – Mihai
Я заявил в вопросе, что он занимает 6 минут. Кроме того, индекс, который вы называете хорошим, не связан с вопросом/вопросом, поскольку ROW_NUMBER() SORT является настолько дорогостоящим. – Namrehs
Индекс плохой, так как он начинается с 'same_voter', который фильтруется' <> 1' (если большинство значений не равно «1», и ваш индекс фильтруется). Я бы рекомендовал изменить начальный столбец индекса на наиболее избирательный в вашем случае. Создание полной таблицы чисел (ROW_NUMBER) для фактического принятия первого/последнего ONE_ не является лучшей идеей. Вы не имеете никаких шансов использовать sql-сервер для использования любого индекса и просто выберите min/max/top1. Ваша задача сервера - перечислить все строки, а затем ... _ok, я возьму сначала one_. –