WordPress: это хорошая идея, чтобы улучшить производительность мета-запросов, добавив налоговый запрос? - PullRequest
0 голосов
/ 01 апреля 2020

Мне известно, что использование таксономий над метаданными предпочтительнее, когда речь идет о группировании сообщений. Простыми словами , это и , это говорят: «используйте мета для уникальных данных и таксономию для повторяющихся данных (тот, который группирует сообщения)».

Но я Интересно, возможно ли улучшить производительность мета-запроса, введя таксономию, которая будет представлять различные диапазоны этой мета?

Предположим, у меня есть магазин с типом пост-продуктов. Каждый продукт имеет цену мета. У меня есть миллионы строк в мета-таблице базы данных. Что если я добавлю таксономию ценового диапазона, которая будет использоваться в интерфейсных фильтрах? Диапазон цен будет примерно таким: «1-100 $», «100-1000 $» и т. Д. c. Пользователь нажимает "100-1000 $" + сортировка по цене. Таким образом, я буду запрашивать посты, помеченные как «100-1000 $», и только после этого отсортирую их по цене мета. Повысит ли это производительность запросов?

И как это можно реализовать, если пользователю разрешено вводить «от» и «в» цену? Вероятно, будет хорошей идеей использовать описанный выше подход и просто добавить мета таксономии для диапазона цен? Это будет выглядеть следующим образом: - пользователь выбирает «90-900 $» - выбирает все термины ценового диапазона, которые соответствуют этому диапазону. Ie. «1–100» и «100–1000» - отправлять запросы, которые находятся в ценовом диапазоне «1–100» и «100–1000» (термины), и устанавливают мета-значение Price как> 90 и <900. Будет ли это также увеличивать производительность? Этот подход требует 2 запроса: получить термины (отфильтрованные по мета-терминам), получить сообщения. </p>

У меня нет шансов проверить это с действительно огромной базой данных, так как все мои проекты не такие большие. Но мне все еще интересно, подойдет ли какой-нибудь из моих подходов для больших сайтов?

Отредактировано (1): Я прилагаю PHP и SQL

Запрос только по мета:

new WP_Query([
    'post_type' => 'my_product',
    'meta_query' => [
        [
            'key'     => 'price',
            'value'   => 90,
            'compare' => '>=',
            'type'    => 'NUMERIC'
        ],
        [
            'key'     => 'price',
            'value'   => 900,
            'compare' => '<=',
            'type'    => 'NUMERIC'
        ]
    ]
]);
EXPLAIN SELECT  SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM  wp_posts
    INNER JOIN  wp_postmeta  ON ( wp_posts.ID = wp_postmeta.post_id )
    INNER JOIN  wp_postmeta AS mt1  ON ( wp_posts.ID = mt1.post_id )
    WHERE  1=1
      AND  ( ( wp_postmeta.meta_key = 'price'
                      AND  CAST(wp_postmeta.meta_value AS SIGNED) >= '90' )
              AND  ( mt1.meta_key = 'price'
                      AND  CAST(mt1.meta_value AS SIGNED) <= '900' ) 
           )
      AND  wp_posts.post_type = 'my_product'
      AND  (   wp_posts.post_status = 'publish'
           OR  wp_posts.post_status = 'acf-disabled'
           OR  wp_posts.post_author = 1 AND  wp_posts.post_status = 'private'
           )
    GROUP BY  wp_posts.ID
    ORDER BY  wp_posts.post_date DESC
    LIMIT  0, 10



1   SIMPLE  wp_postmeta ref     post_id,meta_key    meta_key    767 const   1   Using where; Using temporary; Using filesort    
1   SIMPLE  mt1         ref     post_id,meta_key    meta_key    767 const   1   Using where 
1   SIMPLE  wp_posts    eq_ref  PRIMARY,...         PRIMARY       8 loc.own-acf-plugin.wp_postmeta.post_id  1   Using where 

Запрос по налогу и мета:

new WP_Query([
    'post_type' => 'my_product',
    'meta_query' => [
        [
            'key'     => 'price',
            'value'   => 90,
            'compare' => '>=',
            'type'    => 'NUMERIC'
        ],
        [
            'key'     => 'price',
            'value'   => 900,
            'compare' => '<=',
            'type'    => 'NUMERIC'
        ]
    ],
    'tax_query' => [
        [
            'taxonomy' => 'category',
            'field'    => 'slug',
            'terms'    => [ '0-100', '100-1000' ]
        ]
    ]
])
EXPLAIN SELECT  SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM  wp_posts
    LEFT JOIN  wp_term_relationships  ON (wp_posts.ID = wp_term_relationships.object_id)
    INNER JOIN  wp_postmeta  ON ( wp_posts.ID = wp_postmeta.post_id )
    INNER JOIN  wp_postmeta AS mt1  ON ( wp_posts.ID = mt1.post_id )
    WHERE  1=1
      AND  ( wp_term_relationships.term_taxonomy_id IN (1,2) )
      AND  ( ( wp_postmeta.meta_key = 'price'
                      AND  CAST(wp_postmeta.meta_value AS SIGNED) >= '90' )
              AND  ( mt1.meta_key = 'price'
                      AND  CAST(mt1.meta_value AS SIGNED) <= '900' ) 
           )
      AND  wp_posts.post_type = 'my_product'
      AND  (   wp_posts.post_status = 'publish'
           OR  wp_posts.post_status = 'acf-disabled'
           OR  wp_posts.post_author = 1 AND  wp_posts.post_status = 'private'
           )
    GROUP BY  wp_posts.ID
    ORDER BY  wp_posts.post_date DESC
    LIMIT  0, 10



1   SIMPLE  wp_term_relationships   index   PRIMARY,term_taxonomy_id    PRIMARY 16  
    NULL
    1   Using where; Using index; Using temporary; Using f...   
1   SIMPLE  wp_postmeta             ref     post_id,meta_key       
   meta_key 767 const   1   Using where 
1   SIMPLE  mt1                     ref     post_id,meta_key    meta_key    767 const   1   Using where 
1   SIMPLE  wp_posts                eq_ref  PRIMARY,type_status_date,post_author    PRIMARY 8   loc.own-acf-plugin.wp_term_relationships.object_id  1   Using where 

1 Ответ

0 голосов
/ 04 апреля 2020

Следующие проблемы приводят к снижению производительности. (Я не знаю, что из этого можно улучшить в WP.)

  • OR трудно оптимизировать
  • Два JOINs до wp_postmeta. Можно ли это исправить, сделав JOIN только один раз и сделав BETWEEN..AND..?
  • Добавление дополнительного JOIN (к таксономии) , вероятно, замедляет его.
  • Шаблон схемы EAV все равно не работает.
  • Схема EAV в WP имеет неэффективные индексы. См. http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta
  • SQL_CALC_FOUND_ROWS стоит что-то. В частности, он не может выйти после нахождения нужных 10 (LIMIT).
  • GROUP BY и ORDER BY отличаются, что требует дополнительной сортировки. Если изменить оба параметра на ID, это исправит это.

Даже если одно ваше дополнение поможет, этого будет недостаточно для противодействия другим 6 проблемам.

Возможно, самое большое исправление иметь столбец цифр c, называемый price (и соответствующим образом проиндексированный) в wp_posts. Но это совершенно чуждо философии схемы WP.

...