此查询引用约 3M 条记录,现在需要绝对年龄才能运行。 数据取自 Excel 电子表格,行中包含 Cust/Invoices,列中包含 2016 年至今的每月值。
此查询检查同一个月内是否存在相同/不同产品的值,如果可以忽略,则输出 1;如果后续查询应考虑该值,则输出 0。
我已经为产品设置了一个索引,它负责初始条件,但绝对是子查询杀死了这个:
UPDATE tbl_transactions a
SET ProdInCust_Mnth_Same_SameProd_LowerVal =
CASE WHEN
(
SELECT COUNT(TransactionID)
FROM tbl_transactions_tmp b
WHERE
b.TransactionID<>a.TransactionID AND
b.CustomerRef=a.CustomerRef AND
b.TransMonth=a.TransMonth AND
(
(
(b.Product='PLATINUM') AND
b.TransValue<0
)
OR
(
a.TransValue=0 AND
(b.Product='PLATINUM' OR b.Product='GOLD' OR b.Product='SILVER') AND
b.TransValue<0
)
OR
(
a.TransValue<0 AND
(b.Product='PLATINUM' OR b.Product='GOLD') AND
((b.TransValue=a.TransValue AND b.RowReference>a.RowReference) OR
b.TransValue<a.TransValue
)
)
)
)>0 THEN 1 ELSE 0 END
WHERE Product='GOLD';
解释产生:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 UPDATE a \N index IDX_tbl_transactions_Product PRIMARY 8 \N 2828152 100 Using where
2 DEPENDENT SUBQUERY b \N ref IX_Transactions_SP_ProcessTransAA IX_Transactions_SP_ProcessTransAA 45 finance.a.CustomerRef,finance.a.TransMonth 1 20.7 Using where; Using index
从视觉上看,它说这是一个完整的索引扫描,我认为红色背景表明这很糟糕。
有什么想法可以进一步优化吗?
最佳答案
尝试将子查询的 WHERE 子句中使用的所有字段的索引添加到两个表中,并使用 EXISTS
而不是 COUNT
:
UPDATE tbl_transactions a
SET ProdInCust_Mnth_Same_SameProd_LowerVal =
CASE WHEN EXISTS
(
SELECT TransactionID
FROM tbl_transactions_tmp b
WHERE
b.TransactionID<>a.TransactionID AND
b.CustomerRef=a.CustomerRef AND
b.TransMonth=a.TransMonth AND
(
(
(b.Product='PLATINUM') AND
b.TransValue<0
)
OR
(
a.TransValue=0 AND
(b.Product='PLATINUM' OR b.Product='GOLD' OR b.Product='SILVER') AND
b.TransValue<0
)
OR
(
a.TransValue<0 AND
(b.Product='PLATINUM' OR b.Product='GOLD') AND
((b.TransValue=a.TransValue AND b.RowReference>a.RowReference) OR
b.TransValue<a.TransValue
)
)
)
) THEN 1 ELSE 0 END
WHERE Product='GOLD';
关于mysql - 子查询减慢更新速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53759956/