[英]Wordpress slow query when using NOT EXISTS for meta_query
我在一個相對較小的數據庫(wp_posts 中的 10,000 行和 wp_postmets 中的 100,000 行)上運行查詢,但由於某種原因,查詢需要大約 5 到 7 秒才能執行。
我傳遞給 wp_query 的參數是;
Array(
[post_type] => post
[post_status] => publish
[ignore_sticky_posts] => 0
[posts_per_page] => 1
[orderby] => rand
[meta_key] =>
[meta_value] =>
[order] => DESC
[offset] => 0
[post__not_in] => Array
(
)
[author__in] => Array
(
)
[tax_query] => Array
(
[relation] => AND
[0] => Array
(
[taxonomy] => category
[field] => slug
[terms] => Array
(
[0] => beauty
)
[operator] => IN
[include_children] => 0
)
)
[meta_query] => Array
(
[relation] => OR
[0] => Array
(
[key] => sponsored
[value] => 1
[compare] => !=
[type] => CHAR
)
[1] => Array
(
[key] => sponsored
[value] =>
[compare] => NOT EXISTS
[type] => CHAR
)
)
)
它運行的 SQL 查詢是;
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 )
LEFT JOIN wp_postmeta
ON ( wp_posts.id = wp_postmeta.post_id )
LEFT JOIN wp_postmeta AS mt1
ON ( wp_posts.id = mt1.post_id
AND mt1.meta_key = 'sponsored' )
WHERE 1 = 1
AND ( wp_term_relationships.term_taxonomy_id IN ( 3 ) )
AND ( ( wp_postmeta.meta_key = 'sponsored'
AND wp_postmeta.meta_value != '1' )
OR mt1.post_id IS NULL )
AND wp_posts.post_type = 'post'
AND (( wp_posts.post_status = 'publish' ))
GROUP BY wp_posts.id
ORDER BY Rand()
LIMIT 0, 1
我注意到,當我刪除這部分時,長查詢問題會自行解決;
Array(
[key] => sponsored
[value] =>
[compare] => NOT EXISTS
[type] => CHAR
)
SQL查詢中的哪個是;
OR mt1.post_id IS NULL
我要做的是查找標記為sponsored == 0
或未標記為贊助或非贊助的文章(贊助的meta_key 不存在)。
有人可以向我指出/幫助我如何通過更有效的查詢/wp_query 獲得相同的結果嗎? 或者,如果您可以告訴我為什么OR mt1.post_id IS NULL
會使查詢運行約 5 到 7 秒,而沒有它,查詢需要約 20 毫秒?
重新考慮如何指定“被贊助”。 你目前有
LEFT JOIN wp_postmeta ON ( wp_posts.id = wp_postmeta.post_id )
LEFT JOIN wp_postmeta AS mt1 ON ( wp_posts.id = mt1.post_id
AND mt1.meta_key = 'sponsored'
)
WHERE ( ( wp_postmeta.meta_key = 'sponsored'
AND wp_postmeta.meta_value != '1' )
OR mt1.post_id IS NULL
)
這可能更容易擺脫這兩個 JOIN 並將 WHERE 的那部分更改為
WHERE NOT EXISTS( SELECT 1 FROM wp_postmeta AS m
WHERE m.post_id = wp_posts.id
AND m.meta_key = 'sponsored'
AND m.meta_value = '1' )
而且,一定要有WP Index Improvements 。 它將添加一個有助於該子查詢的索引。
我不能確定,但我認為這是不必要的(並導致額外的中間結果):
GROUP BY wp_posts.id
RAND
和SQL_CALC_FOUND_ROWS
都需要查找具有術語分類 3 的所有行。請提供EXPLAIN SELECT ...
以便我們可以討論是否不必要地查看所有帖子,而不僅僅是分類 3 帖子。 (這可能會導致優化。)
不幸的是,WP 不便於將贊助和分類標志放在 wp_posts 中。 然后,復合索引將導致更快的查詢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.