MYSQL - ЗАКАЗАТЬ И ОГРАНИЧИТЬ

203

У меня есть запрос, который выглядит так:

SELECT article FROM table1 ORDER BY publish_date LIMIT 20

Как работает ORDER BY? Будет ли он заказывать все записи, а затем получить первые 20, или он получит 20 записей и упорядочит их по полю publish_date?

Если это последний, вам не гарантировано получить последние 20 статей.

  • 5
    Обратите внимание, что если некоторые publish_date одинаковы, упорядочение по ним не дает определенных результатов, а это означает, что если вы используете LIMIT для разбиения на страницы, вы можете получить одинаковые элементы на разных страницах!
Теги:
limit
sql-order-by

8 ответов

194
Лучший ответ

Сначала он закажет, а затем получит первую 20. База данных также будет обрабатывать что-либо в предложении WHERE до ORDER BY.

  • 0
    Значит, сроки одинаковы?
  • 4
    Неправильно! LIMIT перерывы ORDER BY . С LIMIT ORDER BY возвращает неверный результат. LIMIT каким-то образом переупорядочивает результирующий набор, возвращаемый ORDER BY
Показать ещё 2 комментария
36

Предложение LIMIT может использоваться для ограничения количества строк, возвращаемых оператором SELECT. LIMIT принимает один или два числовых аргумента, которые должны быть неотрицательными целочисленными константами (кроме случаев, когда используются подготовленные операторы).

С двумя аргументами первый аргумент указывает смещение первой строки для возврата, а второй указывает максимальное количество возвращаемых строк. Смещение начальной строки равно 0 (не 1):

SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

Чтобы получить все строки с определенного смещения до конца результирующего набора, вы можете использовать некоторое большое число для второго параметра. Этот оператор извлекает все строки из 96-й строки до последней:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

С помощью одного аргумента значение указывает количество строк, возвращаемых с начала набора результатов:

SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows

Другими словами, LIMIT row_count эквивалентен LIMIT 0, row_count.

Подробная информация о: http://dev.mysql.com/doc/refman/5.0/en/select.html

  • 0
    Разве это не восстановить строки 5-14?
  • 0
    @adonis Нет, это не так. Пример прямо из документации MySQL
Показать ещё 3 комментария
7

Если есть подходящий индекс, в этом случае в поле publish_date, MySQL не должен сканировать весь индекс, чтобы получить 20 запрошенных записей - 20 записей будут найдены в начале индекса. Но если нет подходящего индекса, то потребуется полное сканирование таблицы.

В 2009 году есть статья в блоге по производительности MySQL.

6

Вы можете добавить [asc] или [desc] в конце заказа, чтобы получить самые ранние или последние записи

Например, это даст вам самые последние записи

ORDER BY stamp DESC

Добавить предложение LIMIT после ORDER BY

  • 2
    Добро пожаловать в stackoverflow. Я думаю, что вы, возможно, неправильно поняли вопрос. Я считаю, что они спрашивали о порядке операций, а не о том, «как сортировать». (Но это спорный вопрос, поскольку на этот вопрос уже был дан ответ;)
5

Так же, как @James говорит, он будет заказывать все записи, а затем получить первые 20 строк.

Таким образом, вы получите 20 первых опубликованных статей, но новые не будут показаны.

В вашей ситуации я рекомендую вам добавить desc в order by publish_date, если вам нужны новейшие статьи, тогда самая новая статья будет первой.

Если вам нужно сохранить результат в порядке возрастания и все еще хотите только 10 новых статей, вы можете попросить mysql отсортировать результат два раза.

Этот запрос будет сортировать результат по убыванию и ограничить результат до 10 (это запрос в круглой скобке). Он по-прежнему будет отсортирован в порядке убывания, и нас это не устраивает, поэтому мы просим mysql сортировать его еще раз. Теперь у нас есть последний результат в последней строке.

select t.article 
from 
    (select article, publish_date 
     from table1
     order by publish_date desc limit 10) t 

order by t.publish_date asc;

Если вам нужны все столбцы, это делается следующим образом:

select t.* 
from 
    (select * 
     from table1  
     order by publish_date desc limit 10) t 

order by t.publish_date asc;

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

  • 2
    Ваша дополнительная сортировка может практически не оказывать какого-либо измеримого влияния на производительность, поскольку она ограничена только 10 строками / элементами :-). В общем случае сортировка таблицы в памяти (которую производит подвыбор) выполняется очень быстро и едва поддается измерению, если только у вас нет миллионов строк или если СУБД не выполняет разбиение результирующего набора на диск, поскольку она не помещается в память (в этом случае в зависимости от СУБД также может отменить запрос).
4

Вы можете использовать этот код SELECT article FROM table1 ORDER BY publish_date LIMIT 0,10 где 0 - начальный предел записи и 10 номеров записей

  • 7
    Нет, это не обязательно . LIMIT 10 является сокращением для LIMIT 0,10 .
  • 2
    да, не требуется для LIMIT 0,10, но вы можете требовать Like This Limit 10,20
1

LIMIT обычно применяется как последняя операция, поэтому результат сначала будет отсортирован, а затем ограничен до 20. Фактически сортировка прекратится, как только будут найдены первые 20 отсортированных результатов.

  • 11
    Ваше второе предложение идет вразрез с вашим первым. Сортировка не может быть остановлена, когда найдены первые 20 результатов, потому что, как вы сказали, сортировка будет выполнена до того, как результаты будут возвращены. MySQL может знать только первые 20 результатов после завершения сортировки.
  • 0
    @ На самом деле это возможно, если упорядочить по индексируемому столбцу. Это объясняется здесь: dev.mysql.com/doc/refman/5.7/en/limit-optimization.html
0

Также синтаксис LIMIT отличается от баз данных, например:

mysql - LIMIT 1, 2

postgres - LIMIT 2 OFFSET 1

Ещё вопросы

Сообщество Overcoder
Наверх
Меню