Иногда нужно перебрать много записей из базы. Если таблицы большие, то сразу выбрать все - довольно тупое решение, поэтому обычно выбираются записи с лимитом. Вначале первые N, потом от N до 2N и т.д. Недавно я узнал, что использовать конструкцию с лимитом ( LIMIT n, m ) на больших таблицах - не верно, потому что при выборке скажем:
SELECT * FROM table WHERE true LIMIT 100500, 100600;
вначале выберутся 100600 записей, а потом отбросятся 100500, т.е. в двусторонних лимитах вначале выбирается все до последнего предела, а потом уже отбрасывается то что не нужно. Я раньше как-то не задумывался, но на огромных таблицах - это просто фатально для базы
Оказалось, что есть решение и для этой проблемы. Вполне логичное, но пока яблоко не упадет бывает так и не догадаешься до очевидных вещей. Суть идеи в том, чтобы помнить не позицию, а последний айдишник записи, его подставлять в WHERE и уже потом делать односторонний быстрый лимит.
Например:
SELECT * FROM table WHERE id>100500 LIMIT 100;
Такое будет гораздо быстрее работать на больших базах (а иногда только оно и будет работать
). Конечно, не самый красивый костыль, но какой есть
все красиво, только вот если с базы удалялись поля или что то в этом роде, а id авто_инремент, будет ссув по полю, в итоге запись 100500!=записи с ид 100500. потому так делать нельзя
Нет ну ясен пень, что если попутно будет что-то удаляться то тут медицина бессильна.
Насчет же удаления кучи всего - OPTIMIZE TABLE не?
Такое решение редко применимо, так как зачастую используются запросы с сортировками (например по фамилии, дате, сумме и т.п.). Поэтому запоминать надо не значение id записи, а значение поля (полей), по которым идет сортировка.