Просто выберите nth наивысший - PullRequest
2 голосов
/ 02 апреля 2009

Я пытаюсь выяснить, какой самый эффективный способ получить n-ю самую высокую запись в базе данных mySQL:

SELECT * 
FROM table_name
ORDER BY column_name DESC
LIMIT n - 1, 1

или

SELECT *
FROM table_name AS a 
WHERE n - 1 = (
    SELECT COUNT(primary_key_column) 
    FROM products b 
    WHERE  b.column_name > a. column_name)

Существует индекс на имя_ столбца.

Я бы подумал, что MySQL будет эффективно выполнять предложение limit, и первый вариант - это путь.

Мне не очень понятно, что именно делает 2-й запрос, так что, если он более эффективен, кто-нибудь может объяснить, почему.

Спасибо.

Ответы [ 7 ]

2 голосов
/ 02 апреля 2009

Я пробовал EXPLAIN для обоих этих запросов в моей базе данных (примечание: оптимизатор может выбирать разные планы для вашей схемы / данных), и это определенно похоже на то, что первый выигрывает во всех отношениях: его проще читать и понимать и, скорее всего, будет быстрее.

Как сказал Ааронлс, и EXPLAIN подтверждает, что второй запрос имеет коррелированный подзапрос, который потребует дополнительной итерации по всей таблице для каждой строки.

Поскольку первое легче читать, я бы выбрал его в кадре. Если вы обнаружите, что это узкое место (после профилирования вашего приложения), вы можете попробовать второе, но я не понимаю, как это может быть быстрее.

1 голос
/ 02 апреля 2009

Запустите объяснение обоих запросов и посмотрите, какой из них MySQL считает более сложным.

1 голос
/ 02 апреля 2009

Я думаю, что со вторым запросом будет выполнен внутренний цикл для запуска подзапроса для оценки каждой строки в table_name. Если это так, это означает, что у вас может быть что-то вроде времени выполнения O (n ^ 2).

Исходя из этого, я бы лично пошел с первым запросом, но если бы это было так важно для меня, я бы провел некоторое тестирование производительности. Обязательно проверяйте также очень большие наборы данных, чтобы получить представление о масштабах производительности. То, что работает с O (n), быстрее для очень маленьких наборов данных, но то, что работает с O (log (n)), намного лучше для больших наборов данных.

0 голосов
/ 10 сентября 2009

для второй по величине записи

выберите max (Price) как цену из OrderDetails где Цена <(выберите max (Цена) из OrderDetails) </p>

для N-й самой высокой записи

SELECT * FROM OrderDetails КАК ГДЕ n-1 = (ВЫБЕРИТЕ СЧЕТ (OrderNo) ИЗ OrderDetails b ГДЕ b.Цена> a. Цена)

0 голосов
/ 02 апреля 2009

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

0 голосов
/ 02 апреля 2009

Я бы посоветовал (хотя сам не уверен в точном синтаксисе SQL), что вы вычисляете дополнительный столбец RANK для простого запроса, который упорядочивает элементы по желанию (DESC). Затем просто выберите строку, где RANK = n.

Вероятно, вы можете сделать это с помощью переменной, которая увеличивается. Это в основном то, что говорит о том, сколько строк находится перед этим рядом, поэтому его должно быть очень легко вычислить.

0 голосов
/ 02 апреля 2009

Это не совсем ответ, но ...

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

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