Коррелированная производительность подзапроса - PullRequest
1 голос
/ 23 марта 2012

Я нашел то, что кажется узким местом в одной из моих хранимых процедур.@Results - табличная переменная с ~ 17K строк.Он включает в себя столбец TimeStamp (DateTime) и столбец Value (десятичное число).

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

Я в основном пытаюсь выбрать наибольшее значение из подмножества полных результатов.Теперь запись результата включается в подмножество путем подсчета всех значений, которые меньше или равны этому значению, умножения на 100, деления на @Count и определения, превышает ли он какой-то процент.

Вот запрос:

SELECT TOP 1 @Result = Results.Value
FROM @Results Results
WHERE (100.0 * (SELECT COUNT(1) 
                FROM @Results Results2
                WHERE Results2.Value <= Results.Value) / @Count) >= @Percent
ORDER BY Results.Value ASC

Буду признателен за любой совет или помощь.

Спасибо!

Ответы [ 2 ]

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

Было бы полезно лучше понять, что именно нужно достичь, выражая его в терминах пользовательского домена, а не в SQL.

Кроме того, весь объем и структура запрашиваемых данных не указаны, но, вероятно, включают отношения, которые участвуют в определении производительности.

Во-первых, есть переменная таблицы Results, которая имеет свое собственное происхождение. Этот метод может быть рискованным, потому что он строит неявную временную таблицу, которая часто является деоптимизатором. Как будто вы пытаетесь навязать стратегию оптимизатору запросов.

Похоже, что вам нужно одно максимальное значение из совокупного запроса, который должен быть оптимизируемым. На самом деле, оптимизация не должна быть проблемой даже с 17K записями.

Можете ли вы повторить это в форме:

SELECT MAX(Value)
FROM some-aggregate-query
GROUP BY fields
HAVING COUNT(something)/COUNT(1) * 100 > @percent

Подсказка: по моему опыту, вы обычно движетесь в неправильном направлении, когда начинаете декомпозировать SQL (что прямо противоположно лучшей политике для процедурного кода).

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

Хм, как насчет этого: во-первых, выберите общее количество строк в переменной. Затем вы выбираете строку с индексом (@Percent / 100.0 * countOfRowsTotal), упорядочивая по значению.

Это будет сканировать таблицу от 1 до 2 раз.

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