wp_postmeta — самая проблемная таблица WordPress. 18 миллионов строк, EAV (Entity-Attribute-Value) паттерн. WordPress создаёт индекс только на (post_id), но запросы часто фильтруют по meta_key и meta_value.
# Анализируем, какие meta_key запрашиваются чаще всего
SELECT
meta_key,
COUNT(*) AS cnt
FROM wp_postmeta
GROUP BY meta_key
ORDER BY cnt DESC
LIMIT 20;
# Результат:
# +---------------------------+----------+
# | meta_key | cnt |
# +---------------------------+----------+
# | _edit_last | 2400000 |
# | _edit_lock | 2400000 |
# | _wp_old_slug | 1850000 |
# | _thumbnail_id | 2100000 |
# | custom_seo_title | 2400000 |
# | custom_seo_description | 2400000 |
# +---------------------------+----------+
# Текущий план запроса — Full Table Scan!
EXPLAIN SELECT post_id, meta_value
FROM wp_postmeta
WHERE meta_key = '_thumbnail_id'
AND post_id IN (1001, 1002, 1003, 1004, 1005);
# type: ALL, rows: 18000000 — катастрофа
Решение — составные индексы:
# Индекс для самых частых запросов
ALTER TABLE wp_postmeta
ADD INDEX idx_meta_key_value (meta_key(191), meta_value(100)),
ADD INDEX idx_postid_metakey (post_id, meta_key(191));
# После индексации:
EXPLAIN SELECT post_id, meta_value
FROM wp_postmeta
WHERE meta_key = '_thumbnail_id'
AND post_id IN (1001, 1002, 1003, 1004, 1005);
# type: ref, rows: 5 — мгновенно
# Проверяем использование индексов через Performance Schema
SELECT
OBJECT_SCHEMA,
OBJECT_NAME,
INDEX_NAME,
COUNT_STAR AS uses,
ROUND(SUM_TIMER_WAIT / 1000000000, 2) AS total_wait_ms
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = 'wordpress'
AND OBJECT_NAME = 'wp_postmeta'
ORDER BY COUNT_STAR DESC;
Результат: среднее время запроса к wp_postmeta упало с 5.7 мс до 0.3 мс — ускорение в 19 раз.
Оставить комментарий