mysql - 子查询减慢更新速度

标签 mysql indexing mysql-dependent-subquery

此查询引用约 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';

引用:Is EXISTS more efficient than COUNT(*)>0?

关于mysql - 子查询减慢更新速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53759956/

相关文章:

mysql - 如何使用 WHERE、RANGE 和 SORT 设置 MySql 表的索引?

sql - 索引 bool 字段

mysql - 如何防止 CASE WHEN x THE(子查询)中出现依赖子查询

mysql - MySQL 中的错误 "Every derived table must have its own alias"是什么?

mysql - MySQL 中的错误 "Every derived table must have its own alias"是什么?

php - 在 MYSQL 中搜索具有西类牙口音的圣经网站字符集

php - 添加数据库目录路径

mysql - 缓慢的 MySQL 左连接查询

php - 如何在 PHP 中打印到 Excel 电子表格时替换从 MySQL DB 中提取的某些值?

sql - 索引是否有助于列数多但记录数少的表?