`
wx1569632409
  • 浏览: 116294 次
文章分类
社区版块
存档分类
最新评论

MYSQL的UPDATE子查询,UPDATE时避免使用子查询

 
阅读更多

大概率

 

MYSQL的UPDATE子查询,UPDATE时避免使用子查询

近日写mysql储存过程的时候,有个SQL执行不动:

UPDATE t_csi_comment
SET is_valid = 0
WHERE
        comment_id IN (
                SELECT
                        comment_id
                FROM
                        (
                                SELECT
                                        *
                                FROM
                                        t_csi_comment
                                WHERE
                                        DATE_FORMAT(comment_time, '%Y%m%d') BETWEEN 20170425
                                AND 20170528
                                ORDER BY
                                        comment_id DESC
                        ) a
                GROUP BY
                        openid,
                        dlr_code
                HAVING
                        count(1) > 2
        );
很奇怪,按道理这条SQL的检索量小于10W,应该怎么慢也不会几分钟不动的地步。

单独执行子查询:

SELECT
        comment_id
FROM
        (
                SELECT
                        *
                FROM
                        t_csi_comment
                WHERE
                        DATE_FORMAT(comment_time, '%Y%m%d') BETWEEN 20170425
                AND 20170528
                ORDER BY
                        comment_id DESC
        ) a
GROUP BY
        openid,
        dlr_code
HAVING
        count(1) > 2;
结果比想象中的快,1秒都不到,EXPLAIN后检索量不到4W行。我就郁闷了。

EXPLANIN第一条update语句:



注意:select_type 里出现了 DEPENDENT SUBQUERY。

这意味着什么?——子查询取决于外面的查询,Mysql 先执行外查询,内查询根据这个查询结果(如执行计划里所述,38196 rows)的每一条记录组成新的查询语句后执行。多重子查询情况下,我已经不想去解析它是如何转换SQL了。 Mysql在这点上并不比人类聪明。

解决办法(子查询转换成联表查询):

UPDATE t_csi_comment a INNER JOIN
 (
        SELECT
                comment_id
        FROM
                (
                        SELECT
                                *
                        FROM
                                t_csi_comment
                        WHERE
                                DATE_FORMAT(comment_time, '%Y%m%d') BETWEEN 20170425
                        AND 20170528
                        ORDER BY
                                comment_id DESC
                ) a
        GROUP BY
                openid,
                dlr_code
        HAVING
                count(1) > 2
) b ON a.comment_id = b.comment_id;
SET a.is_valid = 0
        


毫秒级别完工。

按理说,越复杂的程序逻辑关系要越明朗,出现复杂SQL的几率要越低。但是总会有一块业务相对复杂多变,无法把控,或者就是整个系统的架构不够明朗,脱离不了复杂SQL。这是在UPDATE时发现的子查询问题,在其它SQL语句中肯定也会有所体现,这是Mysql的查询机制问题,子查询会让Mysql变笨。所以还是慎用子查询,各种复杂SQL下尽量先测试吧。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。互联网+时代,时刻要保持学习,携手千锋PHP,Dream It Possible。

转载于:https://my.oschina.net/u/3432750/blog/911855

分享到:
评论

相关推荐

    MySQL锁类型以及子查询锁表问题、解锁1

    在实际应用中,可能会遇到死锁问题,特别是在涉及子查询的更新语句中。如描述中所示,如果一个事务在更新时对子查询中的表进行锁定,可能导致其他事务尝试获取已被锁定的资源,从而引发死锁。MySQL在检测到死锁时会...

    MySQL数据库update更新子查询

    总的来说,理解并掌握如何在`UPDATE`语句中正确使用子查询是MySQL数据库操作中的一个重要技能。合理利用`JOIN`或并列子查询,可以有效地避免`1093`错误,实现对数据的准确更新。在设计和编写这类语句时,要确保遵循...

    MySQL 数据库考核选择题 带答案 测试题 期末题.docx

    - **查询优化**:合理使用索引、避免使用SELECT *、减少子查询等。 - **服务器配置调优**:调整缓存大小、优化内存分配等。 #### 9. 复杂查询 - **子查询**:在SELECT语句中嵌套另一个SELECT语句。 - **联接查询**...

    MySql高级Sql查询

    当我们谈论“MySQL高级SQL查询”时,通常是指那些超越基础SELECT、INSERT、UPDATE和DELETE语句的复杂查询技巧。这些技巧包括联接操作、子查询、聚合函数、窗口函数、集合操作、存储过程和触发器等。本资料包中的" ...

    使用案例加深对MySQL SQL查询理解

    有时,可以使用JOIN或临时表来替代子查询,从而提高性能。 此外,GROUP BY和HAVING子句用于分组和筛选数据,它们常与聚合函数(如COUNT、SUM、AVG等)一起使用。在处理大量数据时,合理地使用GROUP BY和HAVING可以...

    Mysql数据库中子查询的使用

    在MySQL中,子查询通常被包含在圆括号中,它可以在SELECT、INSERT、UPDATE、DELETE语句中作为表达式的一部分出现。 我们来看一个子查询的例子: ```sql SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2)...

    MySQL海量数据查询优化策略.

    10. 使用EXISTS代替IN:在子查询中使用EXISTS通常比使用IN执行更快,尤其是在大表和小表的关联查询中,因为EXISTS在找到第一个匹配项后即停止搜索。 11. 使用表的别名:在复杂查询中使用表的别名可以提高代码的...

    MySQL嵌套查询的例子

    MySQL中的嵌套查询(也称为子查询)是指在一个查询中嵌套另一个查询。子查询可以出现在SELECT、INSERT、UPDATE或DELETE语句中,通常用于返回一个结果集,该结果集可以作为外部查询的一部分进行进一步处理. 嵌套查询...

    MySql数据库中的子查询与高级应用浅析

    例如,当子查询使用`IN`操作符且列表很大时,可能会导致索引无法充分利用,此时可以考虑使用`JOIN`操作来优化。另外,对于多列子查询,可以尝试使用`UNION ALL`替代多个单列子查询,以减少查询次数。 总的来说,...

    MySQL SELECT同时UPDATE同一张表问题发生及解决

    然而,当你试图在同一个SQL语句中同时使用 `SELECT` 从一个表中获取数据并更新该表时,MySQL会抛出错误,因为它不支持在 `FROM` 子句中直接引用作为 `UPDATE` 目标表的表。这种限制可能会在某些复杂的数据处理场景下...

    Mysql联表update数据的示例详解

    - 当使用UPDATE JOIN时,确保你的连接条件是正确的,以防止意外更新大量数据。 - 使用WHERE子句进一步限制更新的行,避免不必要或错误的更新。 - 谨慎处理NULL值,因为在JOIN操作中,NULL值可能产生意想不到的...

    mysql api查询手册

    MySQL API查询手册是一份详尽的参考资料,专为开发者提供关于如何使用MySQL应用程序接口(API)进行数据库查询和管理的指导。这份手册以CHM( Compiled HTML Help)格式呈现,通常这种格式便于离线查阅,内容清晰且...

    mysql5.6.19下子查询为什么无法使用索引

    MySQL中的子查询与索引的使用是一个复杂的话题,特别是在不同版本之间可能会存在性能差异。这里我们探讨一下在MySQL 5.6.19版本中,为何子查询可能无法充分利用索引,以及可能导致性能下降的原因。 首先,让我们...

    里面包含mysql的整个数据库的学习资料,包含建表,外键,模糊查询,子查询,内连接等

    - 子查询是嵌套在其他SQL语句中的查询,通常用于SELECT、INSERT、UPDATE、DELETE语句中。 - 模糊查询使用LIKE关键字配合通配符(%表示任意字符出现任意次数,_表示任意单个字符)进行不精确匹配。 9. MySQL的配置...

    MySql常用查询命令操作大全

    以上是MySQL的一些基础查询和操作命令,实际上MySQL支持更复杂的查询语法,如JOIN、GROUP BY、HAVING、子查询等,以及视图、存储过程、触发器等高级功能,这些都可以帮助用户更高效地管理和处理数据库中的数据。...

    mysql update语句的用法详解

    同时,`ON UPDATE`功能允许InnoDB表与其他表同步更新,但目前不支持在子查询中更新同一表。 最后,一个简单的`UPDATE`示例: ```sql UPDATE publishers SET city = 'Atlanta', state = 'GA' WHERE state = 'NY'; `...

    mysql查询分析器

    用户可以方便地运行各种查询,包括SELECT、INSERT、UPDATE、DELETE以及复杂的JOIN和子查询。 2. **数据库设计与建模**:通过该分析器,用户可以创建、修改和删除数据库表结构,设置索引和外键关系。此外,它还支持...

    MySQL的子查询中FROM和EXISTS子句的使用教程

    MySQL数据库在处理复杂查询时,子查询是一种非常重要的工具,它可以让我们在主查询中嵌套一个或多个查询,以获取所需的数据。本文将重点讲解在MySQL中如何使用FROM子查询和EXISTS子句。 首先,我们来看FROM子查询。...

Global site tag (gtag.js) - Google Analytics