Начните с работы с ключом SELECT
:
SELECT post_id
from
(
SELECT *
from wp_postmeta
) AS X
where meta_key = 'attribute_pa_beden'
and meta_value in (".$size.")
and post_id in (
SELECT post_id
from
(
SELECT *
from wp_postmeta
) AS Y
where meta_key = 'attribute_pa_renk'
and ((meta_value = '".$color."')
OR ('".$color."' = 'all_colors'))
)
and post_id in (
SELECT id
from wp_posts
where post_type = 'product_variation'
and post_parent in (
SELECT object_id
FROM wp_term_relationships
where term_taxonomy_id in (".$urun.")))
)";
Да, я понимаю, что вам нужно "спрятать" wp_postmeta
от UPDATE wp_postmeta
, но мы можем изменить положение вещей, чтобы сделать его болееэффективный.Обратите внимание, как у вас есть два случая получения всей wp_postmeta
до фильтрации?Это делает невозможным использование каких-либо индексов, следовательно, это sloooow.
SELECT m1.post_id
FROM wp_postmeta AS m1
JOIN wp_postmeta AS m2 USING(post_id)
JOIN wp_posts AS p2 USING(post_id)
JOIN wp_term_relationships AS tr ON p2.post_parent = tr.object_id
WHERE m1.meta_key = 'attribute_pa_beden' AND m1.meta_value in ("$size")
AND m2.meta_key = 'attribute_pa_renk' AND ( m1.meta_value = '$color'
OR '$color' = 'all_colors' )
AND p2.post_type = 'product_variation'
AND tr.term_taxonomy_id IN ($urun)
Забудьте о UPDATE
, пока не получите отладку SELECT
.(Возможно, я допустил некоторые ошибки, но не выглядит ли это намного проще? Он будет работать намного быстрее, особенно с индексами, которые я рекомендую.)
OR
с цветом, вероятно, будет оптимизировантак что я не буду беспокоиться об этом.
Я не могу предсказать, с какой из 4 таблиц оптимизатор запустится, поэтому эти индексы необходимы для выбора:
tr: (term_taxonomy_id, object_id) -- in this order
posts: (post_type, post_id) -- in this order
postmeta: (meta_key, meta_value) -- see note below
После того, как Оптимизатор выберет, с какой таблицы начинать, он перейдет к каждой из других таблиц по очереди;заказ не имеет значения для нас.Эти дополнительные индексы могут быть полезны:
posts: (post_parent, post_id) -- in this order
postmeta: (post_id, meta_key, meta_value) -- see note below
Если meta_value
равно LONGTEXT
, то не может быть в индексе, поэтому не указывайте его.(Нет, не беспокойтесь о «префиксном» индексе.)
Если вы используете MySQL 5.5 или 5.6, meta_key
слишком длинный, чтобы быть индексами;см. мою ссылку для нескольких обходных путей.
Схема EAV отстой, и вы выясняете, почему.
Обратно к kludge для UPDATE
Добавьте обертку:
UPDATE wp_postmeta AS m
JOIN ( SELECT post_id
FROM ( the above query )
) AS kludge USING (post_id)
SET m.meta_value = 'outofstock'
WHERE m.meta_key = '_stock_status'