`
wsdtq123
  • 浏览: 47627 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类

记一次sql优化,in+子查询

sql 
阅读更多
拿到一个sql,同事告诉我这个sql索引加了,为什么还是这么慢。
sale_order_goods,sale_order 两张表都有几十万的数据。其中in结果集有30万。

sql如下:
SELECT	
	ifnull(sum(buy_number), 0) AS buy_number_sum
FROM
	sale_order_goods
WHERE
	sale_order_id IN (
		SELECT
			so.id 

		FROM
			sale_order_goods sog,
			sale_order so
		WHERE
			1 = 1
		AND sog.tenant_org_id =1
		AND so.tenant_org_id =1
		AND sog.sale_order_id = so.id 

		AND so.order_status =1
		AND DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(sog.created_at)
	);


这是一个in + 子查询的语句。

顺便提一句,innodb对in + 子查询的处理非常差,比如:
select * from a where a.oid in (select id from b where b.name='xxx')
,如果
select id from b where b.name='xxx'
返回的结果是1,2,3。那么sql是不是就变成了
select * from a where a.oid in (1,2,3)
. NO!!,事实上不是这样。innodb会把外层表压入到子查询中,sql会变成
select * from a exists (select * from b where name='xxx' and b.id = a.oid)

这时,子查询关联外部表a,所以innodb认为无法执行这个子查询,于是需要全表遍历一遍a,再根据a返回的oid逐个执行一次子查询。

上面这个sql不需要执行子查询,改写如下:
SELECT
			ifnull(sum(buy_number), 0) AS buy_number_sum
		FROM
			sale_order_goods sog,
			sale_order so
		WHERE
			1 = 1
		AND sog.tenant_org_id =1
		AND so.tenant_org_id =1
		AND sog.sale_order_id = so.id 

		AND so.order_status =1
		AND DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(sog.created_at)


直接放弃 in + 子查询的方式。sql在1秒内执行完毕。
分享到:
评论

相关推荐

    Microsoft+SQL+Server+2008技术内幕:T-SQL查询_源代码及附录A

    理解子查询的使用和优化是编写复杂查询的必备技能。 “数据聚合和透视”涉及到GROUP BY、HAVING和聚合函数(如COUNT、SUM、AVG、MIN和MAX)。这些功能用于汇总数据,而透视则允许我们从不同角度查看数据,例如通过...

    非常好用的SQL语句优化34条+sql语句基础

    15. **使用EXISTS而非IN**:当子查询仅用于判断是否存在匹配记录时,EXISTS通常比IN更快。 16. **使用UNION而非UNION ALL**:只有在确保没有重复记录时才使用UNION ALL,因为它不进行去重操作,速度更快。 17. **...

    SQL+SERVER+2008+学习笔记

    - **IN**: 检查值是否存在于子查询结果中。 - **EXISTS**: 检查子查询是否有结果。 ##### 2.10 外联结、交叉联结和自联结 - **LEFT OUTER JOIN**: 包含左表的所有记录。 - **CROSS JOIN**: 两个表的所有组合。 - **...

    Oracle+SQL优化

    #### 一、Oracle SQL优化概览 在系统开发与维护过程中,随着数据库数据量的增长,SQL语句的性能优化成为提升系统响应速度的关键环节。优化SQL不仅能够显著提升数据处理效率,还能大幅节省硬件资源,减少运维成本。...

    SQL Server高级查询与T-SQL编程知识点汇总

    - **子查询优化**:子查询效率取决于结果集大小,与连接查询相比,各有优势,具体场景需灵活选择。 5. **数据应用**: - **DDL语句**:包括创建和删除数据库、创建和修改表结构等操作。 - **DML语句**:涉及数据...

    JAVA-SQL语句优化.doc

    SQL优化能够显著提升系统的响应速度,尤其是在数据库中数据量剧增的情况下,良好的SQL编写技巧可以使得查询速度提升上百倍。 首先,要注意SQL语句的编写规范。在多表联接查询时,应考虑表的连接顺序。通常,应将...

    常用查询sql语句(简单+高级)

    2. **子查询**:在查询中嵌套另一个查询,通常用于提供临时结果集。例如: ```sql SELECT column1 FROM table1 WHERE column1 IN (SELECT column2 FROM table2); ``` 3. **联接(UNION)操作**:用于合并两个或...

    Oracel SQL高级编程笔记

    子查询可以用于比较、联接、集合操作等,例如在WHERE子句中使用IN、NOT IN、ANY、ALL等操作符。 2. **连接查询(JOIN)**:连接查询允许合并来自两个或更多表的数据。Oracle支持多种类型的JOIN,包括INNER JOIN、...

    sql书写优化和性能优化

    在子查询中,应当在子查询前后加上括号,例如 `SELECT col1, col2 FROM table_a WHERE col3 IN (SELECT col4 FROM table_b WHERE col4 &gt; 0)`。 **10. 避免使用无意义的表达式** 避免在WHERE子句中使用诸如`1=1`或`...

    sql优化心得

    - **使用EXISTS代替IN**:当查询涉及子查询时,使用EXISTS通常比IN更高效,因为前者可以在找到第一个匹配项后立即停止搜索。 - **避免SELECT * FROM**:指定所需的列名而非使用星号(*),这样可以减少不必要的...

    SQL优化过程中常见Oracle中&quot;HINT&quot;的30个用法

    在进行SQL优化的过程中,Oracle中的`HINT`是一种非常实用且强大的工具,它允许数据库管理员或开发者通过在SQL语句中添加注释的方式直接指导Oracle的优化器如何执行查询计划。这种方式可以有效地调整数据访问路径、...

    SQL等价改写优化案例精选

    然而,通过巧妙运用`CASE WHEN`语句,可以将这些子查询合并为一个更加简洁高效的查询语句,从而减少表扫描次数,提升查询性能。 原始SQL: ```sql SELECT DISTINCT ne_state.peer_id peer_name, to_char(ne_state....

    Oracle中实现MySql中limit+SqlServer分页+分页的存储过程

    1. **NOT IN子查询**: ```sql SELECT * FROM a_matrix_navigation_map WHERE rowid NOT IN (SELECT rowid FROM a_matrix_navigation_map WHERE rownum ) AND rownum ; ``` 2. **嵌套查询**: ```sql ...

    sql+中间件+网络知识等上市公司实施运维人员面试笔试题

    - SQL查询语句`SELECT id, je FROM sy WHERE id IN (SELECT id FROM zc WHERE bbq='200704' AND ts&gt;rc) AND bbq='200704' ORDER BY je DESC`是基于两个表(Sy和Zc)的数据筛选,使用了子查询(IN子句)和ORDER BY...

    SQL语句的优化及SQL 性能调整原则

    SQL语句的优化是提升数据库系统性能的关键环节。在开发初期,由于数据量较小,可能无法明显察觉到SQL语句的性能差异,但随着数据的...SQL优化是一个持续的过程,需要不断学习和实践,以便适应不断变化的数据和需求。

    SqlServer2008查询优化研究报告

    本文介绍了在SqlServer2008环境下进行查询优化的方法和技巧,包括Sargability规则、AND/OR操作符的调优、用NOT EXISTS代替NOT IN以及避免使用COUNT(*)的子查询等。通过对这些规则的实际应用和实验验证,证明了它们...

    SQL Server T-SQL高级查询

    - **子查询**:嵌套在另一个SQL查询中的查询。 - 子查询可以用于SELECT、INSERT、UPDATE和DELETE语句中。 - 根据子查询返回的结果数量,可以分为标量子查询、行子查询和表子查询。 #### 9. 特定数据类型查询 - ...

    关于oracle的sql优化资料

    - **HASH_AJ(v)** 和 **MERGE_AJ(v)**: 控制使用散列反连接或合并反连接处理NOT IN子查询。 - **HASH_SJ(v)** 和 **MERGE_SJ(v)**: 控制使用散列或合并半连接处理EXISTS子查询。 - **PUSH_JOIN_PRED(v)** 和 **NO_...

    SQL优化.pptx

    #### 一、SQL优化概述 在数据库管理系统中,SQL(Structured Query Language)是用于管理和处理数据的核心语言。随着数据量的增长和技术的发展,如何提高SQL执行效率成为了一个重要的课题。本章节将从多个方面详细...

    SQL优化 '%5400%' LIKE操作符

    尤其是在子查询中使用它们时更应该小心。可以考虑用 `EXISTS` 或 `NOT EXISTS` 替代 `IN` 和 `NOT IN`,以提高查询性能。 - **使用 `IS NULL` 和 `IS NOT NULL`**:相比于 `column IS NULL` 和 `column IS NOT NULL`...

Global site tag (gtag.js) - Google Analytics