Один клиент попросил меня помочь ускорить импорт через плагин WP All Import.
Они используют WP All Import для импорта своих товаров и обновления цен и других деталей, и хотя вначале импорт работал быстро, он постепенно замедлился до такой степени, что стал давать сбои.
Scalability Pro — это плагин, который я создал, чтобы помочь оптимизировать подобные вещи — он добавляет недостающие индексы в ключевые таблицы WordPress и даже переписывает SQL-запросы, где это необходимо, чтобы помочь им использовать индексы в своих таблицах.
В этом примере показано увеличение скорости до и после использования Scalability Pro и дополнительного бесплатного плагина для устранения некоторых размеров изображений.
На скорость импорта действительно влияют 3 ключевые вещи:
- Проверка того, должно ли произойти обновление или вставка (или оно должно быть полностью пропущено). Также включает выборочный выбор данных для обновления.
- Выполнение обновления/вставки
- Импортирование изображений
Установление базового уровня и сбор показателей
Перед проведением исследования мне нужно установить базовый уровень скорости, чтобы сравнить показатели до и после. Во время выполнения этой базовой линии я также могу собрать медленные запросы в журнале медленных запросов mysql.
С установленным журналом медленных запросов и без установленного или активированного Scalability Pro я запустил один из импортов, на который жаловался клиент. Их основная проблема заключается в том, что они хотят постоянно повторять очень большой импорт, который обычно не требует обновления продуктов, но может это сделать — это означает, что большое внимание уделяется первой части любого импорта — проверке того, существует ли продукт или изменились ли данные.
Они предоставили мне для оптимизации большое задание по импорту 225 000 продуктов. По своему опыту я знаю, что «Прошедшее время», показываемое WP All Import, регулярно ошибочно — например, с момента начала импорта прошло 20 минут, но он утверждает, что прошло только 10 минут.
Итак, у нас есть базовый уровень 1100 обновлений за 20 минут. Давайте установим Scalability Pro и улучшим скорость импорта.
Ускорение импорта с помощью Scalability Pro
Я установил и активировал Scalability Pro, а затем на странице настроек создал индексы, которые он использует. Я установил одну опцию в Scalability Pro: «Отложить подсчет сроков до ночи».
Я снова запустил импорт, снова засекая 20 минут, поскольку я не могу доверять тому, что WP All Import говорит в своем таймере истекшего времени.
С установленным Scalability 4.52, активным подсчетом отложенных сроков, созданными индексами, мы видим, что за 20 минут обрабатывается 1300 записей вместо 1100. Это довольно плохо, поэтому очевидно, что что-то недавно изменилось.
Изучение журнала запросов
Прошло некоторое время с тех пор, как я оптимизировал Scalability Pro специально для импорта, поэтому сейчас я исследую журнал запросов, чтобы узнать, можно ли еще увеличить скорость.
Журнал запросов представляет собой список медленно выполняющихся запросов, которые превысили временной лимит, установленный в конфигурационном файле mysql. В нашем случае мы установили 0,1 в качестве предела, при котором запрос считается медленным, или 100 миллисекунд.
В первую очередь я ищу шаблоны запросов — то есть запросы, которые фактически являются однотипными, но только данные меняются.
Первое, что я увидел в журнале медленных запросов, было то, что WP All Import имеет новые таблицы ссылок, к которым он обращается. Эти таблицы могут стать большими при большом импорте, поэтому для поддержания хорошей скорости требуются индексы.
Все медленные запросы, связанные с wp_pmxi_hash, используют post_id и import_id. Я исследовал оба этих параметра и обнаружил, что post_id является наиболее избирательным, т.е. именно он должен получить индекс, чтобы при использовании индекса быстро добраться до нужных строк, а не сканировать таблицу.
В целом, я нашел три новых случая, когда индексы могут ускорить импорт с помощью WP All Import:
create index wpallimport_boost1 on wp_wc_product_meta_lookup (sku);
create index wpallimport_boost2 on wp_pmxi_posts(unique_key(10));
create index wpallimport_boost3 on wp_pmxi_hash(post_id);
Все три типа запросов были простыми поисками, все они выполнялись примерно за 0,15 секунды, что сократилось до незначительного значения (< 0,001 секунды) после добавления индексов.
После добавления индексов я очистил файл slow.log и повторно запустил импорт, чтобы собрать больше информации.
Итак — за это время мы обработали 2600 строк по сравнению с 1100 до этого, так что мы имеем чуть более чем 2-кратное увеличение скорости импорта из Scalability Pro с этими 3 новыми индексами. Тем не менее — я считаю это медленным, так что что-то идет не так с оптимизацией. Я очистил файл slow.log и запустил импорт снова и обнаружил следующее:
Технически было 3 шаблона SQL (различные типы SQL-запросов), которые я видел при свежем импорте. Однако 2 из них возникли только в начале, когда WP All Import настраивает импорт для запуска — добавление индексов увеличивает требования к хранению и может замедлить импорт и обновление, поэтому я стараюсь минимизировать их количество. В данном случае мне нужно оптимизировать только один запрос.
SELECT COUNT( DISTINCT ID ) FROM wp_posts p
LEFT JOIN (
SELECT object_id
FROM wp_term_relationships
WHERE term_taxonomy_id IN ( 23838 )
) AS exclude_join
ON exclude_join.object_id = p.ID
INNER JOIN (
SELECT object_id FROM wp_term_relationships
INNER JOIN wp_term_taxonomy using( term_taxonomy_id )
WHERE term_id IN ( 23846 )
) AS include_join ON include_join.object_id = p.ID
WHERE 1=1
AND p.post_status = 'publish'
AND p.post_type = 'product'
AND exclude_join.object_id IS NULL;
Из журнала slow.log видно, что этот запрос повторяется для каждой импортированной строки. Я также знаю из своих контрольных показателей, что мы получаем чуть больше 3 импортируемых элементов в секунду. Этот запрос занимает около 0,23 секунды, так что если в секунду происходит 3 таких запроса, то это 0,7 секунды времени только на один повторяющийся запрос.
Это означает, что если мы сможем оптимизировать этот запрос, чтобы он выполнялся за 0,01 секунды или что-то подобное, то мы сэкономим 0,7 секунды с каждой секунды и теоретически увидим, что импорт будет выполняться в 3 раза быстрее (0,3 секунды для 3 строк вместо 1 секунды = в 3 раза быстрее). Учитывая, что Scalability Pro уже увеличил скорость чуть более чем в два раза, это приведет к 6-кратному увеличению скорости импорта с помощью WP All Import.
Я также могу сказать из запроса, что этот запрос подсчитывает видимые элементы в категории ‘Uncategorized’, т.е. он пытается подсчитать термины. Существует функция WordPress, которая обычно управляет этим — wp_defer_term_counting — но похоже, что она не используется конкретным процессом. Псевдоним таблицы exclude_join определенно не похож на обычные псевдонимы WordPress, которые генерируются в WP_Query. Поэтому я поискал в кодовой базе утверждение exclude_join:
Оптимизация импорта WooCommerce с помощью WP All Import
Исследуя файл wc-term-functions.php в поисках exclude_join, я обнаружил функцию _wc_term_recount, которая обходит стандартные правила WordPress для пересчета терминов. Однако я нашел полезный фильтр внутри функции:
Поясним: подсчет терминов означает подсчет всех продуктов по категориям для обновления хранящихся в базе данных подсчетов терминов. Эта операция является дорогостоящей — 0,23 секунды, которые мы видели ранее — и, учитывая, что мы выполняем импорт, нет никакого смысла выполнять этот подсчет для каждой строки, когда подсчет изменится буквально менее чем за секунду.
Поэтому для оптимизации мне нужно было изменить код, чтобы пересчет сроков выполнялся только после завершения импорта.
Я изменил Scalability Pro двумя ключевыми способами — во-первых, если у пользователя включена опция «отложить подсчет сроков до ночи», то все инструменты импорта WooCommerce будут ускорены благодаря этой функциональности — однако подсчет сроков будет неточным до 2 часов ночи следующего дня.
Во-вторых, если вы используете WP All Import (единственный инструмент импорта, который я рекомендую — он потрясающий), то независимо от того, установили ли вы отсрочку подсчета сроков, он отключит пересчет сроков в начале партии импорта и запустит подсчет сроков в конце партии импорта.
Если вы используете другой инструмент импорта, дайте мне знать об этом в комментариях ниже, и, возможно, я смогу добавить код, специфичный для этого плагина импорта, чтобы ускорить его работу — как я уже сказал, все инструменты импорта ускорятся, если вы включите ‘Defer Term Counts’, но количество терминов будет неточным, пока они не будут пересчитаны в 2 часа ночи. Если ваш плагин импорта предоставляет действия до и после импорта, я могу добавить специальный код для этих действий, чтобы ускорить этот инструмент импорта.
Ускорение импорта изображений
Импорт изображений — одна из самых медленных частей импорта товаров с помощью любого инструмента импорта, не только WP All Import. Импорт изображений можно ускорить, уменьшив количество импортируемых изображений, избегая их импорта вообще, импортируя их на другой сервер или ускоряя ваши диски.
WordPress хранит изображения в нескольких размерах, поэтому за годы установки плагинов у вас могут появиться десятки размеров изображений. Все они должны быть созданы для каждого импортируемого элемента, что занимает много процессора и памяти.
Контроль над этими размерами изображений скоро появится в Scalability Pro — в частности, мы добавим функцию ограничения размеров изображений только при импорте определенных типов постов (например, использовать размеры изображений WooCommerce только при импорте продуктов). Тем временем, есть два плагина, которые могут помочь — наш собственный плагин External Images полностью устраняет необходимость импортировать изображения вообще, поэтому является самым быстрым. Это означает, что в ваших файлах импорта должно быть стороннее место, где будут находиться изображения, например, CDN партнерской сети или другой сторонний сервер, где изображение будет доступно.
Часто владельцы магазинов хотят иметь изображения на собственном сервере, возможно, по соображениям SEO, поэтому в этом случае лучшим подходом будет сокращение количества создаваемых изображений.
В случае с этим клиентом скорость обновления важнее, чем скорость вставки, поскольку они сосредоточены на повторном выполнении конкретного задания импорта, но я все равно хотел, чтобы у них был быстрый начальный импорт, поэтому я установил плагин Stop Generating Unnecessary Thumbnails и деактивировал ненужные им эскизы.
Резюме
Я повторно выполнил основной импорт 225 000 продуктов, чтобы измерить скорость импорта после всех моих изменений. В моем первоначальном эталоне 1100 записей обрабатывались в течение 20 минут. Теперь, с новыми дополнениями к Scalability Pro для устранения ненужного подсчета терминов в WooCommerce, 10 900 записей обрабатываются в течение 20 минут — это увеличение скорости в 9,9 раза! Помните — устранение подобной нагрузки не только ускорит импорт, но и сделает ваш сайт более удобным, быстрым и удобным в использовании во время импорта.
Если у вас небольшие файлы импорта, вы не заметите такого 10-кратного увеличения скорости, но если у вас еще большие файлы импорта, то влияние будет еще более значительным. Я бы предположил, что если у вас в файле импорта 1 миллион товаров, то вы увидите увеличение скорости импорта в 100 раз или, возможно, больше.
Из интереса, весь еженедельный импорт 225 000 продуктов теперь завершается чуть более чем за 6 часов, в то время как раньше он постоянно тормозил и выходил из строя, его приходилось перезапускать каждый день, и в итоге он даже не завершался в течение недели.
Я добавил эти 3 новых индекса, код WP All Import и обновленный код ‘Defer Term Count’ в Scalability Pro 4.63. Если вы используете другой инструмент импорта, вы также увидите увеличение скорости, но ваши подсчеты сроков будут неточными после импорта до 2 часов ночи. Если вы используете другой инструмент импорта, дайте мне знать в комментариях ниже, и я изучу их код и посмотрю, могу ли я добавить аналогичную функциональность, чтобы увеличить скорость импорта и сохранить точность подсчета сроков.
Источник: Speeding up WP All Import imports using Scalability Pro
Источник: https://www.kobzarev.com/wordpress/speeding-up-wp-all-import-imports-using-scalability-pro/