sql优化-把派生表改成子查询,查询速度将变快
SQL 优化 查询 速度 改成 派生
2023-09-11 14:19:52 时间
使用数据库:MYSQL 5.7.27
参考资料:
数据库~Mysql派生表注意的几点~关于百万数据的慢查询问题
https://blog.csdn.net/weixin_34146410/article/details/93984487
子查询:在一个查询中嵌套另一个查询,则另一个查询成为子查询,也叫内部查询
派生表:在FROM子句中使用子查询时,从子查询返回的结果集将用作临时表。 该表称为派生表
当查询的复杂sql数据量大时,把 派生表 改成 子查询, 查询速度将变快
因为派生表不能走索引,子查询可以走索引
两张表:
ding_talk_employee 钉钉员工表: 总共408条数据
![](https://img2020.cnblogs.com/blog/1129695/202111/1129695-20211117143600286-2026890008.png)
ding_talk_employee_analysis 钉钉员工统计年份分析表: 总共2259条数据
![](https://img2020.cnblogs.com/blog/1129695/202111/1129695-20211117143521430-537921779.png)
在数据量比较小时: 派生表查询速度比子查询快一倍
派生表sql:
SELECT t0.department_name, t0.department_id, -- 上一年度正式人员 IFNULL(t1.beforeYearNormalCount,0) as beforeYearNormalCount, -- 当前正式人员 IFNULL(t2.normalCount,0) as normalCount, -- 较上年新增正式人员数 IFNULL(t2.normalCount,0)-IFNULL(t1.beforeYearNormalCount,0) as normalCompareBeforeYearCount, -- 试用人员 IFNULL(t3.probationCount,0) as probationCount, -- 人员折算总计 IFNULL(t4.sumCoefficient,0) as sumCoefficient from ( select MIN(a.department_name) as department_name, a.department_id, count(1) from ding_talk_employee a where a.department_name !='' -- and dimission_remarks !='不统计' group by a.department_id ORDER BY department_name ) as t0 LEFT JOIN ( -- 上一年度正式人员 SELECT a.department_id, count( 1 ) AS beforeYearNormalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = DATE_ADD('2021-01-01 00:00:00', INTERVAL - 1 YEAR ) AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) AS t1 on t1.department_id=t0.department_id LEFT JOIN ( -- 当前正式人员 SELECT a.department_id, count( 1 ) AS normalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) AS t2 on t2.department_id=t0.department_id LEFT JOIN ( -- 试用人员 SELECT a.department_id, count(1) AS probationCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status = '2' GROUP BY a.department_name ) AS t3 on t3.department_id=t0.department_id LEFT JOIN ( SELECT a.department_id, SUM(dtea.coefficient) AS sumCoefficient FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE dtea.count_year = '2021-01-01 00:00:00' GROUP BY a.department_id ) AS t4 on t4.department_id=t0.department_id
不使用缓存的查询时间
派生表查询时间 0.047s
使用 explain 命令查看索引使用情况
总共5个派生表,看索引情况,派生表会自动创建索引
查看具体耗时步骤:
使用命令:
show profiles (查询刚才执行sql的对应id) show profile for query 26
派生表转换成子查询后的sql:
SELECT tu.department_name, tu.department_id, -- 上一年度正式人员 tu.beforeYearNormalCount, -- 当前正式人员 tu.normalCount, -- 较上年新增正式人员数 IFNULL(tu.normalCount,0)-IFNULL(tu.beforeYearNormalCount,0) as normalCompareBeforeYearCount, -- 试用人员 tu.probationCount, -- 人员折算总计 tu.sumCoefficient FROM ( SELECT MIN(t0.department_name) as department_name, t0.department_id, IFNULL( ( -- 上一年度正式人员 SELECT count( 1 ) AS beforeYearNormalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = DATE_ADD('2021-01-01 00:00:00', INTERVAL - 1 YEAR ) AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) ,0) as beforeYearNormalCount, IFNULL( ( -- 当前正式人员 SELECT count( 1 ) AS normalCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status IN ( '3', '5' ) GROUP BY a.department_id ) ,0) as normalCount, IFNULL( ( -- 试用人员 SELECT count(1) AS probationCount FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' AND dtea.employee_status = '2' GROUP BY a.department_name ) ,0) as probationCount, IFNULL( ( SELECT SUM(dtea.coefficient) AS sumCoefficient FROM ding_talk_employee a INNER JOIN ding_talk_employee_analysis dtea ON a.userid = dtea.userid WHERE a.department_id=t0.department_id AND dtea.count_year = '2021-01-01 00:00:00' GROUP BY a.department_id ) ,0) as sumCoefficient FROM ding_talk_employee t0 WHERE t0.department_name !='' -- and dimission_remarks !='不统计' GROUP BY t0.department_id ORDER BY t0.department_name ) as tu
使用子查询的查询时间0.068s
相关文章
- sql server 优化 案例
- SQL Server 2014内存优化表的使用场景
- mysql的慢查询实战+sql优化
- SQL Server 中 EXEC全称execute 与 SP_EXECUTESQL动态执行sql代码语句 的区别
- 第七章 SQL表之间的关系
- SQL 优化经历:从 30248.271s 到 0.001s
- 数据库SQL优化大总结之 百万级数据库优化方案
- SQL Server下7种“数据分页”方案,全网最全
- SQL查询优化
- SQL Server: Get table primary key and Foreign Key using sql query
- SQL Server 查询性能优化——创建索引原则
- Sql语句优化-查询两表不同行NOT IN、NOT EXISTS、连接查询Left Join
- SQL优化 查询语句中,用 inner join 作为过滤条件和用where作为过滤条件的区别
- SQL Server 优化---为什么索引视图(物化视图)需要with(noexpand)强制查询提示
- SQL Server SQL性能优化之--通过拆分SQL提高执行效率,以及性能高低背后的原因
- SQL Server 查询性能优化——创建索引原则(一)
- 浅析SQL中 in 与 exists 用法的区别及其各自执行流程、not in/not exists区别、sql优化应该如何选择in还是exists
- SQL优化:慎用标量子查询,改用left join提升查询效率
- SQL审核:OR展开与子查询优化案例详解
- 性能为王:SQL标量子查询的优化案例分析
- SQL Server查询优化器:最佳执行计划
- SQL Server查询性能优化之创建合理的索引(上)
- (1.12)SQL优化——mysql表名、库名大小写敏感
- (1.10)SQL优化——mysql 常见SQL优化
- (1.9)SQL优化——mysql导入导出优化
- sql-如何提高SQL查询的效率?