форум общения русскоязычных пользователей CMS Текстпаттерн
Вы не зашли.
Столкнулся с неприятной особенностью MySQL 5, которая проявилась при апгрейде с MySQL 4
Столкнулся при использовнии ТхП, но проблема общая.
Особенность сайта была в большом размере (около 100 Мб) базе.
и там, в шаблоне ТхП, использовался случайный вывод заголовков статей на каждой странице.
После апгрейда - начало безудержно расти дисковое пространство, росла загрузка процессора и сайт просто затыкался.
После разбора полетов, оказалось, что MySQL сервер для случайного выбора считывает ВСЮ таблицу, потом пересортировывает ее и выдает результат.
Все работает нормально, пока таблица помещается в память.
Но как только памяти не хватает, начинается работа с диском. Т.е. таблица копируется на диск, во временную таблицу, там же пересортировывается, затем оттуда считывается, видимо, начальные строки, в соответствии с limit-ом, затем временная таблица удаляется. При более-менее приличном количестве посетителей, количество этих временных таблиц начинает расти как снежный ком и все просто умирает.
В MySQL 4 это же самое, похоже, реализовано было по другому. Думаю, что считывались только ИД записей (то есть сами временные файлы были значительно меньше), после пересортировки которых шло дополнительное обращение к базе, за нужными случайными записями.
То есть, теоретически, разработчики MySQL 5 улучшили систему, убрав "лишние" обращения...
Но, как оказалось на практике - это улучшение может вылезать боком :-(
Хостер уверяет, что сам MySQL сервер настроен правильно, то есть такая странная работа не явялется следствием кривых рук админов.
Это я к тому, что если у вас MySQL 5 и база становится большой, то надо (далее- только для ТхП) внимательно относиться к каждому использованию rand () при использовании тэгов article и article_custom.
Либо - стандартная рекомендация хостера - берите отдельный сервер и конфигурируйте его под себя.
Неактивен
Я думаю выход можно найти если самому сформировать запросы к базе. Идея в том, чтобы выбирать из таблицы textpattern (таблица, где хранятся все статьи) только id статьи и не брать "тяжелые" данные, вроде самого тела статьи. Когда выборку по нашим условиям сделали и получили список нужных нам id, то можно выбрать нужное нам кол-во случайных id и затем запросить из базы полный комплект данных для этих id
Вот так мне кажется это будет правильно с точки зрения рациональности нагрузок.
Неактивен
Есть аналогичная проблема с абсолютно другим движком. Более того - сомописным. Сайт - портал, являющийся лидером в своей области, после апгрейда MySQL стал тормозить так, что было принято решение о его полной переделке, т.к. писавшая его команда разошлась, а разбираться со всем кодом довольно дорого. А пока идёт поиск "вредных" запросов и их "вырезание".
Так что наличие проблемы "под 4.ХХ летало, а после агрейда до 5.ХХ лежит" подтверждаю.
Неактивен
the_ghost написал:
выход можно найти если самому сформировать запросы к базе.
Выходы найти конечно можно.
Я вот не экспериментировал еще как работает rand() при limit=1 в MySQL-5-сервере.
Для поиска одной случайной записи не нужно создавать копию таблицы (что необходимо при выводе неограниченных limit-ов, для исключения повторений), но как реализовано это в данной версии сервера - неясно. Возможно они обошлись одним общим случаем. А может быть и нет.
Но сейчас речь не об этом.
Речь шла про внимательный подход к использованию стандартных тэгов и атрибутов ТхП, которые формируют SQL запрос вида
select *, unix_timestamp(Posted) as uPosted from textpattern where 1=1 and Status = 4 and Posted <= now() and Section IN ('news') order by rand() limit 0, 20]
выполнение MySQL сервером версии 5 именно такого запроса (абсолютно корректного!) и приводит к неработоспособности.
в MySQL версии 4 он отрабатывался на ура.
Справедливости ради надо сказать, что затык происходит только в случае объемных таблиц, либо маленького лимита на выделенную под MySQL сервер память.
Эта проблема решается увеличением лимита памяти, что на виртуальных серверах сделать невозможно.
По крайней мере, мне договориться об этом не удалось.
Пришлось ограничить использование rand()
Неактивен
Думаю проблема в том, что при использовании "select * ..." и "sort rand()" в памяти начинают крутить большое кол-во данных. А как с этим можно бороться с помощью оптимизации - я написал выше. Правда, это скорее новый скрипт, чем оптимизация, но, тем не менее, должно помочь
Неактивен
Какие могут быть решения "неприятной особенности"?
my.cnf
key_buffer = 1M max_allowed_packet = 16M table_cache = 4 sort_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 1M net_buffer_length = 2K thread_stack = 64K
Параметры сервера VDS
Память адресуема/гарантированная
4608/1536 Мб
CPU
2000 МГц
Ощутимая потеря скорости из-за тега recent_article, но он крайне необходим.
Установлен - Textpattern 4.0.8
Пока попробывал:
<txp:article_custom section="article" category="<txp:category1 link="0" />" listform="headline" form="headline" limit=8 />
Быстрее, но все равно заметно теряется скорость, и это не совсем то, что нужно, т.к. выводит первые 8, а не случайные.
Хотелось бы найти другое решение.
PS: Более правильный раздел, имхо, "Textpattern: установка, апгрейд и хостинг"
Отредактированно bons (01-12-2009 01:33:07)
Неактивен
0. добавьте в свой код "Пока пробовал" атрибут sort="rand()" - получите случайную соритровку
1. тег-в-теге работает, если окружить значение атрибута одинарными кавычками
2. все атрибуты должны быть в кавычках
3. включите режим отладки и отыщите запрос, который вам больше всего не нравится - от этого и плясать
Неактивен
Мой тест показал, что
<txp:article_custom section="article" category="<txp:category1 link="0" />" listform="headline" form="headline" limit="10" sort="rand()" />
жрет больше, чем
<txp:recent_articles />
Примерно, так:
SQL (2,18828606606) против SQL (0,880808830261) - несколько раз запускал, могу ошибаться, т.к. запускал со сторонней нагрузкой.
Случайная сортировка, имхо, фигово для поисковых роботов(она каждый раз разная). Я не правильно выразился в предыдущем посте. Плохо, не то, что не случайно, плохо, например, когда в категории из 100 статей выводится в каждой отдельно будут одни и те же ссылки(к примеру, 10 шт.). Оптимальный вариант - ускорить тег recent_articles насколько это возможно.
Отредактированно bons (01-12-2009 05:46:54)
Неактивен
Какой размер базы? Сколько статей? Какой средний их размер? Как точно выглядит провинившийся запрос?
Неактивен
как уже сказал выше the_ghost, поставьте одинарные кавычки, там где вложенный тег, т.е. код должен быть таким
<txp:article_custom section="article" category='<txp:category1 link="0" />' listform="headline" form="headline" limit="10" sort="rand()" />
а потом уже скорость меряйте.
Неактивен