美文网首页
MySQL Delete子查询优化

MySQL Delete子查询优化

作者: 会飞的毯子 | 来源:发表于2018-02-01 15:47 被阅读0次

问题

工作中需要删除某个品牌和类目下的商品属性,于是编写了下面的SQL:

DELETE FROM `product$propertyvalue` WHERE pv_componentid IN(
SELECT cmp_id FROM `product$component` WHERE cmp_brid=7616 and AND_kiid=357)

其中product$propertyvalue这张表有上亿条记录,执行过程中直接报sql timeout,进入数据库命令行show processlist,发现这条语句的状态为preparing

解决

通过explain分析语句

mysql> explain DELETE from `product$propertyvalue` where pv_componentid in(
    -> select cmp_id from `product$component` where cmp_brid=7616 and cmp_kiid=357);

输出结果如下:

+----+--------------------+-----------------------+------------+-----------------+-------------------------------------------------------+---------+---------+------+----------+----------+-------------+
| id | select_type        | table                 | partitions | type            | possible_keys                                         | key     | key_len | ref  | rows     | filtered | Extra       |
+----+--------------------+-----------------------+------------+-----------------+-------------------------------------------------------+---------+---------+------+----------+----------+-------------+
|  1 | DELETE             | product$propertyvalue | NULL       | ALL             | NULL                                                  | NULL    | NULL    | NULL | 62850680 |   100.00 | Using where |
|  2 | DEPENDENT SUBQUERY | product$component     | NULL       | unique_subquery | PRIMARY,BRID_CODE_UNIQUE,FK_tdw4lqwf17ggyewqvcgqh3tyf | PRIMARY | 8       | func |        1 |     5.00 | Using where |
+----+--------------------+-----------------------+------------+-----------------+-------------------------------------------------------+---------+---------+------+----------+----------+-------------+
2 rows in set (0.01 sec)

可以看到语句根本没有用到索引,执行过程中做了全表扫描,难怪会超时。
所以这里想法设法要让其用到索引。于是有了下面的语句:

DELETE `product$propertyvalue` 
FROM
    `product$propertyvalue`,
    ( SELECT cmp_id FROM `product$component` WHERE cmp_brid = 7616 AND cmp_kiid = 357 ) a 
WHERE
    `product$propertyvalue`.pv_componentid = a.cmp_id;

此时explain的结果为:

+----+-------------+-----------------------+------------+------+-------------------------------------------------------+---------------------------+---------+------------------------------------+------+----------+-------------+
| id | select_type | table                 | partitions | type | possible_keys                                         | key                       | key_len | ref                                | rows | filtered | Extra       |
+----+-------------+-----------------------+------------+------+-------------------------------------------------------+---------------------------+---------+------------------------------------+------+----------+-------------+
|  1 | SIMPLE      | product$component     | NULL       | ref  | PRIMARY,BRID_CODE_UNIQUE,FK_tdw4lqwf17ggyewqvcgqh3tyf | BRID_CODE_UNIQUE          | 9       | const                              |    1 |     5.00 | Using where |
|  1 | DELETE      | product$propertyvalue | NULL       | ref  | PROPERTYVALUE_P_CMP_INDEX,PROPERTYVALUE_CMPID_INDEX   | PROPERTYVALUE_P_CMP_INDEX | 9       | mall_prod.product$component.cmp_id |   13 |   100.00 | NULL        |
+----+-------------+-----------------------+------------+------+-------------------------------------------------------+---------------------------+---------+------------------------------------+------+----------+-------------+

可以看到这时用到了索引。

总结

以后形如

DELETE FROM 
  table_name1 
WHERE 
  table_name1.column IN (SELECT column2 FROM table_name2 WHERE XXX );

都可以写成

DELETE table_name1 
FROM
    table_name1,
    ( SELECT column2 FROM table_name2 WHERE XXX ) a 
WHERE
    table_name1.column  = a.column 2;

相关文章

  • MySQL Delete子查询优化

    问题 工作中需要删除某个品牌和类目下的商品属性,于是编写了下面的SQL: 其中product$propertyva...

  • 第六章 查询性能优化(下)

    MySQL查询优化器的局限性 关联子查询 MySQL的关联子查询实现的很差,最好改成左外连接(LEFT OUTER...

  • 查询性能优化

    MySQL查询优化器的局限性 关联子查询 MySQL的子查询实现的非常糟糕,最糟糕的一类查询是where条件中包含...

  • Semi-join Materialization 子查询优化策

    本篇为子查询优化系列的第二篇。在上一篇文章 MySQL 子查询优化 中我们介绍了子查询的一些优化策略,也简单介绍了...

  • MySQL性能调优

    MYSQL查询语句优化 mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬...

  • 数据库分页查询

    mysql SELECT * FROM table LIMIT begin(省略即0),pageSize子查询优化...

  • mysql in() 子查询 优化

    mysql in() 子查询 优化 in 如果里面是一个子查询是不会使用索引的 比如 select * fro...

  • MySQL 子查询优化

    有这么一个SQL,外查询 where 子句的 bizCustomerIncoming_id 字段,和子查询 whe...

  • mysql 子查询in优化

    慢sql 查询某个时间点之前有交易的用户3万用户,4万多条订单记录,查询出来数据3046条,耗时600多秒, 优化...

  • MySQL

    MySQL查询优化之道

网友评论

      本文标题:MySQL Delete子查询优化

      本文链接:https://www.haomeiwen.com/subject/yomdzxtx.html