Как правильно создать навигацию для многомиллионной таблицы mysql?
Приветствую, друзья!
Суть вопроса в следующем: есть mysql таблица на несколько млн записей, мне нужно организовать по ней навигацию (например, выводится по 50 записей на страницу), способ с LIMIT SELECT * FROM table LIMIT 900000, 100
не подходит, так как его выполнение занимает слишком много времени.
Таблица постоянно обновляется, записи добавляются каждый день, так же периодически записи будут удаляться (по этой причине не возможна реализация навигации через id записи). Понимаю, что можно сделать навигацию с условием по дням SELECT * FROM table WHERE date='24.06.2014'
т.е. выводить строки, добавленные за сегодня, на след. странице - за вчера и т.д. Но хотелось бы иметь фиксированное количество строк на страницу, допустим 50 строк.
Таблица на стадии проектирования и я могу добавить любые поля или создать еще дополнительные таблицы.
Наставьте на путь истинный! Подскажите, пожалуйста, как правильно строить такого рода запросы к mysql базе на несколько миллионов записей?
1. Можно все таки ввести неразрывный ключ, хранить его в отдельной таблице, пересчитывать его при каждом удалении/добавлении.
2. Сегментирование по датам, по месяцам - внутри каждого сегмента своя пагинация
3. Если не нужна возможность перехода на произвольную страницу - следующая страница это ... where id < $min_id limit 30
где min_id - минимальный id на текущей странице.
4. если число элементов на странице фиксировано - можно хранить справочную таблицу (номер страницы,стартовый id, конечный id) обновлять её при удалении/вставке/по крону
5. применить гибридный подход: я крайне сомневаюсь что бизнес требования подразумевает offset на 900000 строк. Соответствено первые n тысяч записей можно пролистывать через offset, а дальше - по датам например. Так работает livejournal.
сделал тестовую таблицу на 5М записей, всего 2 поля - id (PRIMARY, AUTO_INCREMENT) и data (varchar(100)) запрос SELECT * FROM main LIMIT 4999980, 30
выполняется 1.6466 сек
запрос, как советуют здесь habrahabr.ru/post/217521
SELECT * FROM main
JOIN (SELECT main.id FROM main ORDER BY main.id LIMIT 4999980, 30) as b ON b.id = main.id
выполняется 2.4865 сек
I don't know WTF.
Повторюсь, я не могу использовать WHERE для отбора id, т.к. они будут идти не по порядку и некоторых айди совсем не будет, ведь некоторые записи будут удалены