Есть ли способ установить псевдоним в аргументах meta_query при запуске get_posts()
? Один из моих запросов работает плохо. Для оптимизации я просто должен иметь возможность повторно использовать одну и ту же объединенную таблицу вместо того, чтобы входить в 3 таблицы, когда требуется только один.
Мой текущий пример …
$args = array( 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'abc_type', 'value' => array('puppy', 'kitten'), 'compare' => 'IN', ), array( 'relation' => 'OR', array( 'relation' => 'AND', array( 'key' => 'abc_type', 'value' => 'puppy', 'compare' => '=', ), array( 'key' => 'abc_color', 'value' => 'pink', 'compare' => '=', ), ), array( 'relation' => 'AND', array( 'key' => 'abc_type', 'value' => 'kitten', 'compare' => '=', ), array( 'key' => 'abc_size', 'value' => 'large', 'compare' => '=', ), ), ), ) ); get_posts($args);
который в основном переводит на это в прямом SQL …
SELECT posts.* FROM posts INNER JOIN postmeta ON ( posts.ID = postmeta.post_id ) INNER JOIN postmeta AS mt1 ON ( posts.ID = mt1.post_id ) INNER JOIN postmeta AS mt2 ON ( posts.ID = mt2.post_id ) INNER JOIN postmeta AS mt3 ON ( posts.ID = mt3.post_id ) WHERE 1=1 AND ( ( postmeta.meta_key = 'abc_type' AND postmeta.meta_value IN ('puppy','kitten') ) AND ( ( ( mt1.meta_key = 'abc_type' AND mt1.meta_value = 'puppy' ) AND ( mt2.meta_key = 'abc_color' AND mt2.meta_value > 'pink' ) ) OR ( ( mt3.meta_key = 'abc_type' AND mt3.meta_value = 'kitten' ) AND ( mt4.meta_key = 'abc_size' AND mt4.meta_value = 'large' ) ) ) ) AND posts.post_type = 'abc_mypost' AND ((posts.post_status = 'publish')) GROUP BY posts.ID ORDER BY posts.post_title ASC;
Однако это добавляет 2 дополнительных объединения для настраиваемого мета-поля abc_type
и, поскольку такая производительность сильно пострадала. Можно ли ссылаться на один и тот же псевдоним для нескольких аргументов meta_query? В основном, mt1
и mt3
совершенно не нужны, я должен просто иметь возможность ссылаться на первую таблицу postmeta
которая используется с первой ( postmeta.meta_key = 'abc_type' AND postmeta.meta_value IN ('puppy','kitten') )
. Или, по крайней мере, если я могу установить индивидуальный псевдоним для каждого из них, я мог бы ссылаться на это.
Более оптимальный запрос будет …
SELECT posts.* FROM posts INNER JOIN postmeta ON ( posts.ID = postmeta.post_id ) INNER JOIN postmeta AS mt1 ON ( posts.ID = mt1.post_id ) INNER JOIN postmeta AS mt2 ON ( posts.ID = mt2.post_id ) WHERE 1=1 AND ( ( postmeta.meta_key = 'abc_type' AND postmeta.meta_value IN ('puppy','kitten') ) AND ( ( ( postmeta.meta_key = 'abc_type' AND postmeta.meta_value = 'puppy' ) AND ( mt1.meta_key = 'abc_color' AND mt1.meta_value > 'pink' ) ) OR ( ( postmeta.meta_key = 'abc_type' AND postmeta.meta_value = 'kitten' ) AND ( mt2.meta_key = 'abc_color' AND mt2.meta_value = 'green' ) ) ) ) AND posts.post_type = 'abc_mypost' AND ((posts.post_status = 'publish')) GROUP BY posts.ID ORDER BY posts.post_title ASC;
Мысли?
Я на самом деле не парень базы данных, но однажды я играл по телевизору …
Разве эта часть
SELECT posts.* FROM posts INNER JOIN postmeta ON ( posts.ID = postmeta.post_id ) INNER JOIN postmeta AS mt1 ON ( posts.ID = mt1.post_id ) INNER JOIN postmeta AS mt2 ON ( posts.ID = mt2.post_id )
лучше заменить на
SELECT posts.* FROM posts INNER JOIN postmeta ON (( posts.ID = postmeta.post_id ) and ( posts.ID = mt1.post_id ) and ( posts.ID = mt2.post_id ))
Вероятно, это было бы проще упростить … с некоторым псевдонимом, застрявшим там, в нужном месте, чтобы вы могли использовать остальную часть своего запроса.
Просто мысль…