В сети уже много веток, я просто пытаюсь понять некоторые нюансы, которые меня запутали!
Цитирование ссылка на документ
If you combine LIMIT row_count with ORDER BY, MySQL stops sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast.
и SO поток
It will order first, then get the first 20. A database will also process anything in the WHERE clause before ORDER BY.
Взяв тот же запрос из вопроса:
SELECT article
FROM table1
ORDER BY publish_date
LIMIT 20
допустим, таблица имеет 2000 строк, из которых ожидается, что query вернет 20 строк, теперь взгляд на ссылка на mysql....stops sorting as soon as it has found the first row_count rows.... сбивает меня с толку, поскольку я нахожу это немного двусмысленным !!
Почему написано stops sorting? не применяется ли предложение limit к уже отсортированным данным, возвращаемым через предложение order by (предполагая, что это столбец non-indexed), или я неправильно понимаю, и SQL сначала выполняет limit, а затем сортирует !! ??






Оптимизация, упомянутая в документации, обычно работает только при наличии индекса в столбце publish_date. Значения хранятся в индексе по порядку, поэтому механизм просто выполняет итерацию по индексу столбца, извлекая связанные строки, пока не будет извлечено 20 строк.
Если столбец не проиндексирован, движку обычно необходимо извлечь все строки, отсортировать их, а затем вернуть первые 20 из них.
Также полезно понять, как это взаимодействует с условиями WHERE. Предположим, запрос:
SELECT article
FROM table1
WHERE last_read_date > '2018-11-01'
ORDER BY publish_date
LIMIT 20
Если publish_date проиндексирован, а last_read_date нет, он просканирует индекс publish_date по порядку, проверит связанный last_read_date на соответствие условию и добавит article к набору результатов, если тест завершится успешно. Когда в наборе результатов будет 20 строк, он остановится и вернет его.
Если last_read_date проиндексирован, а publish_date - нет, он будет использовать индекс last_read_date для поиска подмножества всех строк, удовлетворяющих условию. Затем он отсортирует эти строки, используя столбец publish_date, и вернет из него первые 20 строк.
Если ни один столбец не проиндексирован, он выполнит полное сканирование таблицы для проверки last_read_date, отсортирует все строки, соответствующие условию, и вернет первые 20 строк этого.
Если у вас есть несколько строк с одинаковой датой публикации, так что точка отсечения 20 строк заканчивается в группе строк с одинаковой датой публикации, вы можете получить разные результаты своих запросов. Например, вы публикуете 6 статей в день, и все они читаются. Вы всегда будете получать те же 18 из первых 3 дней, но вы получите только 2 из четвертого дня, и какие 2 вы получите, может отличаться в зависимости от того, какой вариант запроса вы используете. Если бы у вас были разные publish_date в каждой строке, вы всегда получите те же 20, независимо от того, какой у них индекс. Индекс меняет способ получения данных mysql, а не то, что вы получаете.
@NoobEditor Если нет повторяющихся значений publish_date, вы должны получить те же результаты. Это просто оптимизации производительности, они не меняют смысла запроса.
если есть дубликаты и критериям соответствует более 20 строк, то непредсказуемо, какие 20 он выберет, и различные оптимизации могут привести к выбору разных значений.
MySQL stops sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result
На самом деле это очень разумная оптимизация в mysql. Если вы используете limit для возврата 20 строк, а mysql знает, что он их уже нашел, то зачем mysql (или вам) заботиться о том, как именно сортируются остальные записи? Это не имеет значения, поэтому mysql перестает сортировать остальные строки.
Если упорядочение выполняется по индексированному столбцу, то mysql может довольно быстро определить, нашел ли он первые n записей.
Привет, Бармар, спасибо за объяснение. Пара сомнений: 1. В зависимости от столбца
indexed,mysqlможет фактически вернуть мне другой набор строк во всех трех случаях, которые вы описали? 2.If publish_date is indexed and last_read_date is not-> поскольку по умолчаниюorder byнаходится вASC, этот запрос фактически не вернет мне самый старыйarticle, поскольку критерии фильтрации указаны вorder by, а не в предложенииwhere? (означает, что в этом случае возвращается самый старыйpublish dateв сочетании сlast read!!!)