gpt4 book ai didi

mysql - 使用自连接和子查询优化 UPDATE SQL 查询

转载 作者:太空宇宙 更新时间:2023-11-03 11:26:42 25 4
gpt4 key购买 nike

我的 SQL 查询更新数据库中的所有股票,但它的工作效率不高,有时我会收到 504 超时错误。该代码工作正常。我怎样才能让它更好地工作。

P.S:请忽略缺少准备好的语句,稍后我会添加它们。

关于表格的一些信息(Wordpress Woocommerce 插件默认表格):

wp_posts:此表包含帖子。 (帖子可以是产品或产品变体。例如产品是蝴蝶 T 恤,产品变体是蝴蝶 T 恤红色大号)。

wp_postmeta:此表包含有关帖子的元信息。例如,产品变体是否有库存,或者它是什么颜色,或者它是什么尺寸。

  //This array gives, which products are there, and their respective categories.
$allProducts = array("Fermuarlı Kapşonlu Sweatshirt" => "'2653','2659'","Kapşonlu Sweatshirt" => "'2646','2651'","Sweatshirt" => "'2644','2650'","Kadın Tişört" => "'2654','2656'","Atlet" => "'2655','2657'","Tişört" => "'2643','2304'");

//Below arrays gives information about, which product variations are out of stock.
$tisort_OutOfStock =array();
$atlet_OutOfStock =array("all_colors"=>"'3xl','4xl','5xl'");
$kadin_tisort_OutOfStock =array("all_colors"=>"'xxl','3xl','4xl','5xl'");
$sweatshirt_OutOfStock =array("beyaz"=>"'xxl','3xl','4xl','5xl'","kirmizi"=>"'xxl','3xl','4xl','5xl'","bordo"=>"'5xl'","antrasit"=>"'5xl'");
$kapsonlu_sweatshirt_OutOfStock =array("gri-kircilli"=>"'5xl'");
$fermuarli_kapsonlu_sweatshirt_OutOfStock =array("gri-kircilli"=>"'5xl'","siyah"=>"'5xl'");

//Reset stocks before updating.
$resetStocks = "UPDATE wp_postmeta set meta_value = 'instock' where meta_key = '_stock_status'";
$wpdb->query($resetStocks);
echo "Stoklar are reseted<br>";

//Foreach product, foreach color, update if product doesn't have stock.
foreach( $allProducts as $key => $urun ){

switch ($key) {
case "Kadın Tişört": $tempArray = $kadin_tisort_OutOfStock; break;
case "Fermuarlı Kapşonlu Sweatshirt": $tempArray = $fermuarli_kapsonlu_sweatshirt_OutOfStock; break;
case "Kapşonlu Sweatshirt": $tempArray = $kapsonlu_sweatshirt_OutOfStock; break;
case "Sweatshirt": $tempArray = $sweatshirt_OutOfStock; break;
case "Atlet": $tempArray = $atlet_OutOfStock; break;
case "Tişört": $tempArray = $tisort_OutOfStock; break;
}

foreach( $tempArray as $color => $size ){

$query = "UPDATE wp_postmeta set meta_value = 'outofstock' where meta_key = '_stock_status' and post_id in
(
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.")))
)";

global $wpdb;
$updatedRowCount = $wpdb->query($query);
}
}

最佳答案

从键 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.")))
)";

是的,我知道您需要从 UPDATE wp_postmeta 中“隐藏”wp_postmeta,但我们可以重新安排内容以提高效率。请注意,您如何在两种情况下获取整个 wp_postmeta before 过滤?这使得无法使用任何索引,因此速度很慢。

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_valueLONGTEXT,那么它不能在索引中,所以把它去掉。 (不,不要为“前缀”索引而烦恼。)

如果您使用的是 MySQL 5.5 或 5.6,meta_key 太长,无法作为索引;看我的 link多种解决方法。

EAV 架构很糟糕,您正在找出原因。

回到 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'

关于mysql - 使用自连接和子查询优化 UPDATE SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53854249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com