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