12,000 запросов для удаления одной категории
Внутренняя реализация управления таксономиями в WordPress — это просто кошмар какой-то. Мало того, что код написан в процедурном стиле (использование ООП помогло бы решить некоторые проблемы с производительностью, которые иначе можно решить только глобальными переменными), он к тому же очень плохо масштабируется.
Я взял свежую дефолтную инсталляцию WordPress 2.8-bleeding, сгенерировал тестовый контент и пошел искать недоработки и проблемы с производительностью. Одну из них я нашел очень быстро: при попытке удалить категорию, в которой была 1,001 ночь запись.
На неслабом сервере это заняло около 20 секунд и… более 12,000 запросов (да-да, двенадцати тысяч, я количеством ноликов, увы, не ошибся).
Лог запросов (application/x-gzip, 75.1 КиБ)
Лог запросов (text/html, 2.5 МиБ)
А всё почему? Из-за одного магического foreach
в wp_delete_term()
:
$terms = wp_get_object_terms($object, $taxonomy, 'fields=ids');
if ( 1 == count($terms) && isset($default) )
$terms = array($default);
else
$terms = array_diff($terms, array($term));
$terms = array_map('intval', $terms);
wp_set_object_terms($object, $terms, $taxonomy);
}
Куда уж проще: выбрать ID всех объектов, связанных с данной таксономией:
FROM wp_term_taxonomy AS tt INNER JOIN wp_term_relationships AS tr USING(term_taxonomy_id)
WHERE tr.term_id = 'TERM ID HERE' AND tr.taxonomy = 'TAXONOMY NAME HERE'
Затем удалить терм к едрене фене и жукам майским:
FROM wp_term_taxonomy AS tt LEFT JOIN wp_term_relationships AS tr USING(term_taxonomy_id)
WHERE tr.term_id = 'TERM ID HERE' AND tr.taxonomy = 'TAXONOMY NAME HERE'
Затем вставить дефолтное значение терма для тех объектов, которые выпали из таксономии: вычитаем из результата, полученного в первом запросе, результат запроса SELECT object_id FROM wp_term_relationship WHERE object_id IN ("список из первого запроса")
. Для полученного результата выполнить один большой INSERT
:
('OBJECT_ID_1', 'DEFAULT_TERM_TAXONOMY_ID', 0), /* ... */ ('OBJECT_ID_N', 'DEFAULT_TERM_TAXONOMY_ID', 0)
После чего сделать UPDATE wp_term_taxonomy SET `count` = `count` + 'количество строк, затронутых INSERT' WHERE term_taxonomy_id = 'DEFAULT_TERM_TAXONOMY_ID'
.
Причём если дефолтное значение терма не задано, то достаточно просто одного DELETE
.
В результате получаем пять запросов вместо 12,000, улучшенную производительность и меньше мусора. За кадром осталась очистка инсулинового кэша WordPress, но идея понятна. Вот только жаль, что оно увидит свет очень нескоро.
Кому интересно: этой проблеме уже целых два года. Обсуждение ведётся в багтрекере.
Ну зато 10 часов назад
# status changed from new to accepted
Что-то я подозреваю что стоит подождать 2.9, может там будет какой-то прогресс, в плане оптимизации производительности.
Ну так пока кого-нибудь не пнёшь, никто шевелиться не будет. Хотя судя по возрасту бага, я сомневаюсь, что в 2.9 сделают — есть и трехлетние баги
В плане быстродействия — я в WordPress разочаровался. С каждым новым релизом он все медленнее по скорости и громаднее по размеру. Если бы я писал CMS, в ядре было бы все самое необходимое, а вся требуемая функциональность бы расширялась за счет плагинов.
Я прямо удивился, после прочтения. Во многих англоязычных обзорах 2.8 как раз отмечалась оптимизация производительности.. Очень жаль, если это не так..
Чем дальше движется прогресс тем всё больщие награмождения мы себе придумываем, но от необходимого никуда неденешса
Мой горячо любимый сплоггер, пожалуйста, научись пользоваться разметкой (закрывать тэги) и выучи, наконец, грамматику и синтаксис русского языка. Спасибо.
Да уж.. К версии вордпресс 3.0 придется переезжать на что-нибудь полегче. Возможно даже Битрикс
Не сочтите за рекламу, но видели ли вы MaxSite CMS? Её делают, устав от тормозов и ограничений вордпресса, и уже сейчас она очень во многом лучше оного.
Вот сравнение
Видел. Но мы используем (нашу сильно патченную) версию WordPress в довольно серьёзных приложениях, и заменять её чем-то другим просто не готовы.
MaxSite CMS мне очень не нравится с её подходом к безопасности. Особенно функция
mso_checkreferer()
. Во-первых, она криво работает со всякими фаерволами, которые блокируют Referer, а во-вторых, она абсолютно не защищает от подмены Referer. Её реализация при должном навыке атакующего никак не защитит от CSRF (ради которого всё и делалось).Я детально не заглядывал в код, но у меня есть подозрения по поводу возможных XSS-уязвимостей (XSS в традиционном понимании).
В MaxCMS большой напряг с плагинами — в WordPress с этим проще.
К тому же у меня есть свои сомнения по поводу её использования на сильно нагруженных сайтах (поддержка транзакций, репликации, возможность масштабирования).
Ну и заниматься поддержкой нескольких систем мне хочется меньше всего — если что идёт не так, меня заказчики по ночам будят
Wave, вот у вас блог на MaxSite CMS. И как оно для обычного блогера, не програмиста? Тяжело привыкать после wp?
Для обычного блоггера, не программиста, обычно мало разницы, на чём вести блог. Что поставят, или что получится поставить. Хоть друпал, хоть нейтрино. МаксСайт — это примерно пятая-седьмая система, которую я щупал. Плюс опыт в php и то, что за развитием системы я следил с самого начала. Так что для меня никаких проблем не было.
Логичность (понятность) и удобность админки и вообще структуры сайта гораздо выше чем у той же джумлы или друпала. Но не хватает некоторых аяксовых возможностей админки вордпресса. Например, редактирование заголовков постов не заходя в редактирование самих постов.
А так — большинство новичков хвалят за удобство и понятность. Но бывает, что некоторые не могут найти очевидных вещей, например, как сменить шаблон.
P.s.
В MaxCMS большой напряг с плагинами — в WordPress с этим проще.
Цитата: «Ну да, если сравнивать абсолютное количество, то WordPress безусловный лидер. Правда есть один немаловажный фактор: плагины к WordPress в основном плодятся от безысходности. Возьмем очень простой пример: разместить в сайдбаре счетчик и какой-нибудь php-код.
[пояснение]
Ну и будет ли блогер в MaxSite CMS бегать и искать другие плагины для вывода рубрик или размещения счетчиков?»
С этим не соглашусь. На мой взгляд, в ядро не стоит запихивать все подряд — смысл туда помещать то, чем будут пользоваться 10% пользователей? Достаточно развитой системы фильтров/хуков. Но это моё ИМХО.
Текстовые виджеты никто не отменял. А размещать произвольный PHP-код — это небезопасно: если через уязвимость ядра/темы/плагина злоумышленник сможет получить доступ к базе, он в этот произвольный PHP-код может запихнуть свой шелл-код. Который потом будет непросто обнаружить.
Ваши записи произвели на меня огромное впечатление, заставили думать по-другому. Продолжайте свои творческие поиски, а я буду следовать за Вами!