Мне пришлось разработать несколько стратегий разбиения на страницы с использованием PHP и MySQL для сайта, который просматривает более миллиона страниц в день. Я угадал стратегию поэтапно:
Многостолбцовые индексы Я должен был сделать это первым, прежде чем пытаться материализовать представление.
Создание материализованного представления . Я создал задание cron, которое выполняло обычную денормализацию таблиц документов, которые я использовал. Я бы SELECT ... INTO OUTFILE ...
затем создал бы новую таблицу и повернул ее:
SELECT ... INTO OUTFILE '/tmp/ondeck.txt' FROM mytable ...;
CREATE TABLE ondeck_mytable LIKE mytable;
LOAD DATA INFILE '/tmp/ondeck.txt' INTO TABLE ondeck_mytable...;
DROP TABLE IF EXISTS dugout_mytable;
RENAME TABLE atbat_mytable TO dugout_mytable, ondeck_mytable TO atbat_mytable;
Это позволило сократить время блокировки на заявленную запись mytable
до минимума, и запросы на нумерацию страниц могли отбросить в материализованном представлении atbat
. Я упростил вышесказанное, оставив фактические манипуляции, которые не важны.
Memcache Затем я создал оболочку для соединения с моей базой данных, чтобы кэшировать эти разбитые на страницы результаты в memcache. Это была огромная победа. Тем не менее, это все еще не было достаточно хорошо.
Пакетная генерация Я написал демон PHP и извлек в него логику разбиения на страницы. Он будет обнаруживать изменения mytable
и периодически преобразовывать из самой старой измененной записи в самую последнюю запись все страницы в файловой системе веб-сервера. С небольшим значением mod_rewrite
я могу проверить, существует ли страница на диске, и обработать ее. Это также позволило мне эффективно использовать обратное проксирование , позволяя Apache обнаруживать If-Modified-Since
заголовки и отвечать с помощью 304
кодов ответов. (Очевидно, я удалил любую опцию, позволяющую пользователям выбирать количество результатов на страницу, неважную функцию.)
Обновлено:
RE count(*)
: При использовании таблиц MyISAM COUNT
не создавало проблемы, когда мне удавалось уменьшить количество конфликтов чтения-записи в таблице. Если бы я делал InnoDB, я бы создал триггер, который обновил соседнюю таблицу с количеством строк. Этот триггер будет просто +1 или -1 в зависимости от операторов INSERT или DELETE.
RE сборщики страниц (колесики) Когда я перешел к агрессивному кешированию запросов, запросы колесика большого пальца также кэшировались, и когда дело дошло до пакетной генерации страниц, я использовал временные таблицы - так что колесико не было проблемой. Многочисленные упрощенные вычисления упрощались, потому что они стали предсказуемым шаблоном файловой системы, который фактически нуждался только в наибольшем числе страниц. Наименьший номер страницы всегда был 1.
Windowed thumbweel Пример, приведенный выше для windowed thumbwheel (<< 4 [5] 6 >>), должен быть довольно простым без каких-либо запросов, если вы знаете свое максимальное число страниц.