Пользовательское хранилище таблиц — быстрее, чем wp_postmeta | Field Forge - Произвольные поля, созданные для скорости
Скачать Войти

Пользовательское хранилище таблиц — быстрее, чем wp_postmeta

Проблема wp_postmeta

Таблица wp_postmeta в WordPress является универсальным хранилищем ключ-значение, прикрепленным к каждому посту. Именно так хранятся post_title, post_content и custom_field_x. Схема выглядит так:

«sql CREATE TABLE wp_postmeta ( meta_id BIGINT(20) PRIMARY KEY, post_id BIGINT(20), meta_key VARCHAR(255), meta_value LONGTEXT, INDEX (post_id), INDEX (meta_key(191)) ); «

Просто. Гибко. Работает для любой пары ключ-значение. И на типичном сайте WordPress с множеством плагинов она огромна — легко достигает миллионов строк на 5-летнем сайте электронной коммерции с множеством заказов и метаданных продуктов.

Проблема N+1 запросов

Вот что происходит, когда вы загружаете страницу архива с 20 постами, каждый из которых имеет 10 пользовательских полей:

«`sql — Запрос 1: Получить посты SELECT * FROM wp_posts WHERE post_type = ‘post’ LIMIT 20;

— Запросы 2-201: Для каждого поста получить каждое поле SELECT meta_value FROM wp_postmeta WHERE post_id = 1 AND meta_key = ‘field_a’; SELECT meta_value FROM wp_postmeta WHERE post_id = 1 AND meta_key = ‘field_b’; — … 198 дополнительных запросов «`

200 отдельных запросов. Каждый запрос выполняется быстро, но накладные расходы на обратные поездки накапливаются. На сайтах, обращающихся к базе данных через сеть (что часто бывает при управляемом хостинге), это может добавить 500 мс+ к каждому просмотру страницы. Кумулятивный сдвиг макета увеличивается. Основные показатели веба падают. SEO страдает.

Проблема повторителей (хуже)

Поля повторителей в ACF хранятся с одной строкой метаданных на подполе на строку. Повторитель с 5 подполями и 10 строками создает 50 записей метаданных на пост. Добавьте 20 постов в архив, и вы получите более 1,000 мета-запросов на одном просмотре страницы. Вот почему сайты с большим количеством ACF известны тем, что замедляются после определенного масштаба.


Архитектура пользовательской таблицы Field Forge

Field Forge хранит значения полей в выделенной таблице wp_fieldforge_values:

«sql CREATE TABLE wp_fieldforge_values ( id BIGINT(20) PRIMARY KEY, post_id BIGINT(20) NOT NULL, field_group_id BIGINT(20) NOT NULL, field_name VARCHAR(255) NOT NULL, parent_id BIGINT(20) NULL, -- для вложенных значений (повторитель/группа/гибкий) row_index INT NULL, -- для позиции строки повторителя value LONGTEXT, INDEX (post_id, field_name), INDEX (post_id, field_group_id), INDEX (parent_id, row_index) ); «

Ключевые отличия от wp_postmeta:

  • Составной индекс на (post_id, field_name) — поиск по конкретному полю на конкретном посте за один запрос
  • Выделенные иерархические столбцы (parent_id, row_index) — вложенные значения (повторитель, группа, гибкий) структурированы, а не соединены в строку
  • Изолировано от основных метаданных — плагины WordPress, записывающие в wp_postmeta, не загрязняют данные полей
  • Индексы, созданные для конкретной цели — запросы, которые фактически выполняет Field Forge, оптимизированы; универсальный wp_postmeta нет

Бенчмарки

Мы провели контролируемые бенчмарки на тестовом сайте с 10,000 постами, каждый из которых имел группу полей, содержащую 15 полей (3 текстовых, 2 WYSIWYG, 1 изображение, 1 повторитель с 5 подполями, 1 гибкое содержимое с 3 типами макетов).

Загрузка страницы архива (20 постов, все поля отрисованы)

wp_postmeta (ACF / SCF) Пользовательская таблица Field Forge
SQL запросы 302 1 (batch_load)
Время запроса (локальная БД) 840ms 95ms
Время запроса (сетевая БД, +20ms RTT) 6,880ms 115ms
Первый контентный рендеринг 2,100ms 340ms

Загрузка страницы одного поста (1 пост, все поля отрисованы)

wp_postmeta Field Forge
SQL запросы 16 1
Время запроса (локальная БД) 45ms 12ms
Время запроса (сетевая БД, +20ms RTT) 365ms 32ms

Массовое обновление полей (100 постов, по 10 полей каждый)

wp_postmeta Field Forge
SQL запросы 1,000 INSERTs 1 многострочный INSERT
Время (локальная БД) 1,240ms 48ms
Время (сетевая БД) 21,240ms 68ms

На базах данных, подключенных к сети (что является стандартом для почти всех управляемых хостингов WordPress — Kinsta, WP Engine, Cloudways, SiteGround Cloud и т.д.), разница драматична. Задержка обратной поездки является доминирующей стоимостью, и Field Forge делает меньше обратных поездок.


API пакетной загрузки

API для разработчиков для явной пакетной загрузки, когда автоматическая предварительная загрузка Field Forge недостаточна:

«`php // Загрузить поля для конкретного набора постов за один запрос $post_ids = [1, 2, 3, 4, 5]; FieldForge::batch_load($post_ids);

// Теперь любой вызов get_field() для этих постов обращается к кэшу foreach ($post_ids as $id) { $hero = get_field(‘hero_title’, $id); // Без запроса к БД } «`

Вызов batch_load() выполняет один запрос WHERE post_id IN (...) и заполняет кэш Field Forge в памяти для всех запрашиваемых постов. Последующие вызовы get_field() являются попаданиями в кэш.

Автоматическая предварительная загрузка

Field Forge подключается к фильтру the_posts в WordPress для автоматической предварительной загрузки полей для основного запроса. Страницы архива, результаты поиска и списки категорий автоматически получают данные полей пакетной загрузки — без необходимости изменения кода.


Интеграция с объектным кэшем

Field Forge уважает API wp_cache_* WordPress:

  • С Redis или Memcached: значения полей кэшируются в объектном кэше с длительным временем жизни. Последующие загрузки страниц обращаются к кэшу, а не к базе данных.
  • С кэшем временных данных по умолчанию: все равно использует внутренний кэш WordPress на протяжении жизненного цикла запроса.
  • Отдельная группа кэша: Field Forge использует свою собственную группу кэша (fieldforge), чтобы не конфликтовать с другими плагинами или основными операциями кэша.

Недействительность кэша происходит автоматически при обновлении или удалении значения поля через хуки действий.


Что это значит на практике

Для сайтов клиентов агентств

Быстрее страницы архива, быстрее результаты поиска, быстрее динамические шаблоны. Основные показатели веба улучшаются. Удержание клиентов улучшается, потому что сайт «ощущается отзывчивым».

Для электронной коммерции на WooCommerce

Страницы со списками продуктов с 30+ продуктами и сложными пользовательскими полями отрисовываются за то же время, что и более простые сайты. Взаимодействия с корзиной покупок быстрее, потому что загрузки метаданных продуктов обрабатываются пакетами.

Для безголового WordPress

Ответы REST API и WPGraphQL быстрее. Генераторы статических сайтов (Next.js ISR, Astro, Nuxt) выполняют меньше запросов к базе данных на сборку. Время сборки улучшается.

Для миграции с ACF / SCF

Совместимость Field Forge с ACF означает, что вызовы get_field() в вашей теме возвращают те же значения — но они поступают из пользовательской таблицы, а не из wp_postmeta. Улучшение производительности происходит прозрачно после миграции.


Когда wp_postmeta подходит

Чтобы быть честным: если на вашем сайте менее 500 постов и простые пользовательские поля (без глубоких повторителей, без гибкого содержимого), подход wp_postmeta работает. Вы не заметите разницы в скорости. Преимущество производительности Field Forge становится значимым в масштабе — 1,000+ постов, сложные повторители или сайты на сетевых базах данных.


Готовы к более быстрым пользовательским полям WordPress?

Получите Field Forge — от $35 в год →

Хранение пользовательских таблиц включено в каждую версию Field Forge, включая бесплатную.

ИИ-ассистент Forge Онлайн

Привет! Я ИИ-ассистент Field Forge. Спрашивайте меня о чём угодно по плагину — настройка, возможности, устранение неполадок или разработка.

Только что
На базе Forge AI · Просмотр документации