业务过程中碰到多个join引起慢SQL问题,数据量不大,但查询很慢,搜到一片BLog,参考解决。

业务过程不记录,以blog内容重现:

原SQL:

select
distinct abc.pro_col1, abc.col3
from
t0 p
INNER JOIN t1 abc
on p.id=abc.par_col2
inner join t2 s
on s.col3=abc.col3
inner join t3 po
on po.id=s.col4
where p.state=2 and po.state=3
order by abc.pro_col1, abc.col3;

以上SQL同:

select select
distinct abc.pro_col1, abc.col3
from t0 p, t1 abc, t2 s, t3 po
where p.id=abc.par_col2
and s.col3=abc.col3
and po.id=s.col4
and p.state=2 and po.state=3
order by abc.pro_col1, abc.col3;

分析优化:

从语义来看,这条SQL是在经过几个JOIN后取其中一个表的两个字段的唯一值。

但是每一次关联,都可能产生冗余的值,所以导致了结果集越来越庞大。

修改建议,每一次JOIN都输出唯一值,减少冗余。即多次JOIN导致查询结果集越来越大(笛卡儿积),可以把过滤条件放在前面。

select
distinct pro_col1, col3 from
(
select
distinct t1.pro_col1, t1.col3, s.col4 from
(
select
distinct abc.pro_col1, abc.col3 from
t1 abc INNER JOIN t0 p
on (p.id = abc.par_col2 and p.state=2)
) t1
inner join t2 s
on (s.col3 = t1.col3)
) t2
inner join t3 po
on (po.id = t2.col4 and po.state=3)
order by t2.pro_col1, t2.col3 ;

以下实例:

postgres=# create table rt1(id int, info text);
CREATE TABLE
postgres=# create table rt2(id int, info text);
CREATE TABLE
postgres=# create table rt3(id int, info text);
CREATE TABLE
postgres=# create table rt4(id int, info text);
CREATE TABLE postgres=# insert into rt1 select generate_series(1,1000),'test';
INSERT 0 1000
postgres=# insert into rt2 select 1,'test' from generate_series(1,1000);
INSERT 0 1000
postgres=# insert into rt3 select 1,'test' from generate_series(1,1000);
INSERT 0 1000
postgres=# insert into rt4 select 1,'test' from generate_series(1,1000);
INSERT 0 1000

对比:

优化后查询:

从执行时间可以看到,优化后的速度何止是快。

最新文章

  1. Android四大组件-Activity
  2. HTML标签汇总
  3. Bootstrap Table 表格参数详解
  4. iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
  5. C#中DataTable使用技巧
  6. php 如何判断一个常量是否已经定义
  7. HDOJ(HDU) 2061 Treasure the new start, freshmen!(水题、)
  8. 开发H5小游戏
  9. Illustrated C#学习笔记(一)
  10. n条直线的最多交点
  11. JAVA工具_PinyinConv
  12. 腾讯IVWEB团队:WebRTC 点对点直播
  13. jemeter工作台设置
  14. 判断是否是IE9浏览器的最短语句 var ie=!-[1,]
  15. django-redis
  16. day05流程控制while循环 流程控制for循环
  17. Python向上取整,向下取整以及四舍五入函数
  18. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP
  19. Docker概念学习系列之Docker与传统虚拟机差异(4)
  20. 常用日期计算SQL语句

热门文章

  1. 利用 Excel 写 C51 的宏定义
  2. Ambari的资源池管理
  3. Source Insight中文字体设置
  4. nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)
  5. crush class实验
  6. 类的特殊成员方法,类的起源type, metaclass
  7. Linux系统层面标配
  8. python开发函数进阶:递归函数
  9. 一种js异步处理方式
  10. springboot成神之——RestTemplate访问Rest