问题SQL

scwksmlcls.wk_cls_c
, scwklrgcls.wk_lrg_cls_nm
, scwkmdlcls.wk_mdl_cls_nm
, scwksmlcls.wk_sml_cls_nm
, scwksmlcls.wk_cls_rmk
FROM
screqrsnsws
INNER JOIN scwkclsreqrsnsws
ON scwkclsreqrsnsws.req_rsn_id = screqrsnsws.req_rsn_id
INNER JOIN scwksmlcls
ON scwksmlcls.wk_sml_cls_id = scwkclsreqrsnsws.wk_sml_cls_id
AND scwksmlcls.wk_sml_cls_id_ek IS NOT NULL
INNER JOIN scwkmdlcls
ON scwkmdlcls.wk_mdl_cls_id = scwksmlcls.wk_mdl_cls_id
AND scwkmdlcls.wk_lrg_cls_id = scwksmlcls.wk_lrg_cls_id
AND scwkmdlcls.wk_mdl_cls_id_ek IS NOT NULL
INNER JOIN scwklrgcls
ON scwklrgcls.wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id
AND scwklrgcls.wk_lrg_cls_id_ek IS NOT NULL
WHERE
screqrsnsws.req_rsn_c = '996N'
AND scwksmlcls.wk_cls_c = '112233'
AND screqrsnsws.req_rsn_id_ek IS NOT NULL
ORDER BY
scwklrgcls.disp_odr
, scwkmdlcls.disp_odr
, scwksmlcls.disp_odr

-- 用到的表

select count(*) from screqrsnsws; --依赖理由 件数:58

select count(*) from scwkclsreqrsnsws; --依頼理由分類 件数:289142

select count(*) from scwksmlcls; -- 小分類 件数:289414

select count(*) from scwkmdlcls; -- 中分類 件数:285223

select count(*) from scwklrgcls; -- 大分類 件数:1962

表定义
create table score.screqrsnsws (
req_rsn_id integer not null
, req_rsn_id_ek integer
, req_rsn_c character varying(4) not null
, req_rsn_nm character varying(20) not null
, fix_assts_tagt_f character varying(1) not null
, pms_i_ymd timestamp without time zone default now() not null
, pms_i_usr character varying(32) default "current_user"() not null
, pms_i_class character varying(128)
, pms_u_ymd timestamp without time zone
, pms_u_usr character varying(32)
, pms_u_class character varying(128)
, primary key (req_rsn_id)
);

req_rsn_id、req_rsn_c、req_rsn_id_ek のindex

create table score.scwkclsreqrsnsws (
req_rsn_id integer not null
, wk_sml_cls_id integer not null
, drct_ind_h_k character varying(1) not null
, pms_i_ymd timestamp without time zone default now() not null
, pms_i_usr character varying(32) default "current_user"() not null
, pms_i_class character varying(128)
, pms_u_ymd timestamp without time zone
, pms_u_usr character varying(32)
, pms_u_class character varying(128)
, primary key (req_rsn_id,wk_sml_cls_id)
);

req_rsn_id,wk_sml_cls_idの複合index
req_rsn_id

create table score.scwksmlcls (
wk_sml_cls_id integer not null
, wk_sml_cls_id_ek integer
, work_lrg_cls_c character varying(2) not null
, wk_mdl_cls_c character varying(2) not null
, wk_sml_cls_c character varying(2) not null
, wk_cls_c character varying(6) not null
, wk_sml_cls_nm character varying(50) not null
, disp_odr integer
, wk_cls_rmk character varying(200)
, pg_dev_hndl_f character varying(1) not null
, fix_assts_tagt_f character varying(1) not null
, pms_i_ymd timestamp without time zone default now() not null
, pms_i_usr character varying(32) default "current_user"() not null
, pms_i_class character varying(128)
, pms_u_ymd timestamp without time zone
, pms_u_usr character varying(32)
, pms_u_class character varying(128)
, wk_dept_c character varying(4)
, wk_lrg_cls_id integer
, wk_mdl_cls_id integer
, primary key (wk_sml_cls_id)
);

wk_sml_cls_id,
work_lrg_cls_c,wk_mdl_cls_c,wk_sml_cls_c复合索引
wk_cls_c
wk_sml_cls_id_ek

create table score.scwkmdlcls (
wk_mdl_cls_id integer not null
, wk_mdl_cls_id_ek integer
, work_lrg_cls_c character varying(2) not null
, wk_mdl_cls_c character varying(2) not null
, wk_mdl_cls_nm character varying(50) not null
, disp_odr integer
, wk_lrg_cls_id integer
, wk_dept_c character varying(4)
, pms_i_ymd timestamp without time zone default now() not null
, pms_i_usr character varying(32) default "current_user"() not null
, pms_i_class character varying(128)
, pms_u_ymd timestamp without time zone
, pms_u_usr character varying(32)
, pms_u_class character varying(128)
, primary key (wk_mdl_cls_id)
);

wk_mdl_cls_id
work_lrg_cls_c,wk_mdl_cls_c
wk_mdl_cls_id_ek

create table score.scwklrgcls (
wk_lrg_cls_id integer not null
, wk_lrg_cls_id_ek integer
, work_lrg_cls_c character varying(2) not null
, wk_lrg_cls_nm character varyin g

通过SQL语句前加"EXPLAIN ANALYZE"执行SQL得到的执行计划

QUERY PLAN
Sort (cost=3589.88..3589.89 rows=1 width=96) (actual time=21816.121..21816.121 rows=1 loops=1)
Sort Key: scwklrgcls.disp_odr, scwkmdlcls.disp_odr, scwksmlcls.disp_odr
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=557.47..3589.87 rows=1 width=96) (actual time=11548.596..21816.102 rows=1 loops=1)
-> Nested Loop (cost=557.47..3585.59 rows=1 width=80) (actual time=11548.550..21816.055 rows=1 loops=1)
Join Filter: (scwkclsreqrsnsws.req_rsn_id = screqrsnsws.req_rsn_id)
-> Nested Loop (cost=557.47..3585.31 rows=1 width=84) (actual time=1.472..21798.988 rows=4401 loops=1)
-> Hash Join (cost=557.47..1413.63 rows=1 width=84) (actual time=1.453..15.100 rows=4401 loops=1)
Hash Cond: ((scwksmlcls.wk_mdl_cls_id = scwkmdlcls.wk_mdl_cls_id) AND (scwksmlcls.wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id))
-> Index Scan using i_scwksmlcls_ek on scwksmlcls (cost=0.00..823.09 rows=4408 width=55) (actual time=0.013..4.404 rows=4401 loops=1)
Index Cond: (wk_sml_cls_id_ek IS NOT NULL)
-> Hash (cost=540.67..540.67 rows=1120 width=37) (actual time=1.420..1.420 rows=1124 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 73kB
-> Index Scan using i_scwkmdlcls_ek on scwkmdlcls (cost=0.00..540.67 rows=1120 width=37) (actual time=0.047..1.051 rows=1124 loops=1)
Index Cond: (wk_mdl_cls_id_ek IS NOT NULL)
-> Index Scan using con_scwkclsreqrsnsws_pri on scwkclsreqrsnsws (cost=0.00..2171.67 rows=1 width=8) (actual time=1.140..4.948 rows=1 loops=4401)
Index Cond: (wk_sml_cls_id = scwksmlcls.wk_sml_cls_id)
-> Index Scan using i_screqrsnsws_alt2 on screqrsnsws (cost=0.00..0.27 rows=1 width=4) (actual time=0.003..0.003 rows=1 loops=4401)
Index Cond: ((req_rsn_c)::text = '996N'::text)
Filter: (req_rsn_id_ek IS NOT NULL)
-> Index Scan using con_scwklrgcls_pri on scwklrgcls (cost=0.00..4.27 rows=1 width=28) (actual time=0.011..0.012 rows=1 loops=1)
Index Cond: (wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id)
Filter: (wk_lrg_cls_id_ek IS NOT NULL)
Total runtime: 21816.279 ms

看了表的定义,索引,执行计划,认为小分类表和中分类表INNERJOIN的条件「AND scwkmdlcls.wk_lrg_cls_id = scwksmlcls.wk_lrg_cls_id」多余。

因为大中小分类表的主键是ID,用主键ID连接应该足够了。去掉此条件的执行时间会明显加快。

EXPLAIN ANALYZE SELECT
scwksmlcls.wk_cls_c
, scwklrgcls.wk_lrg_cls_nm
, scwkmdlcls.wk_mdl_cls_nm
, scwksmlcls.wk_sml_cls_nm
, scwksmlcls.wk_cls_rmk
FROM
screqrsnsws
INNER JOIN scwkclsreqrsnsws
ON scwkclsreqrsnsws.req_rsn_id = screqrsnsws.req_rsn_id
INNER JOIN scwksmlcls
ON scwksmlcls.wk_sml_cls_id = scwkclsreqrsnsws.wk_sml_cls_id
AND scwksmlcls.wk_sml_cls_id_ek IS NOT NULL
INNER JOIN scwkmdlcls
ON scwkmdlcls.wk_mdl_cls_id = scwksmlcls.wk_mdl_cls_id
-- AND scwkmdlcls.wk_lrg_cls_id = scwksmlcls.wk_lrg_cls_id
AND scwkmdlcls.wk_mdl_cls_id_ek IS NOT NULL
INNER JOIN scwklrgcls
ON scwklrgcls.wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id
AND scwklrgcls.wk_lrg_cls_id_ek IS NOT NULL
WHERE
screqrsnsws.req_rsn_c = '996N'
AND scwksmlcls.wk_cls_c = '112233'
AND screqrsnsws.req_rsn_id_ek IS NOT NULL
ORDER BY
scwklrgcls.disp_odr
, scwkmdlcls.disp_odr
, scwksmlcls.disp_odr

QUERY PLAN
Sort (cost=5598.19..5598.20 rows=1 width=96) (actual time=3.270..3.270 rows=1 loops=1)
Sort Key: scwklrgcls.disp_odr, scwkmdlcls.disp_odr, scwksmlcls.disp_odr
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=949.97..5598.18 rows=1 width=96) (actual time=3.254..3.260 rows=1 loops=1)
-> Nested Loop (cost=949.97..5597.80 rows=1 width=76) (actual time=3.245..3.249 rows=1 loops=1)
-> Hash Join (cost=949.97..5429.77 rows=77 width=47) (actual time=3.237..3.241 rows=1 loops=1)
Hash Cond: (scwkclsreqrsnsws.wk_sml_cls_id = scwksmlcls.wk_sml_cls_id)
-> Nested Loop (cost=71.78..4512.75 rows=5075 width=4) (actual time=0.038..0.041 rows=1 loops=1)
-> Seq Scan on screqrsnsws (cost=0.00..2.71 rows=1 width=4) (actual time=0.023..0.025 rows=1 loops=1)
Filter: ((req_rsn_id_ek IS NOT NULL) AND ((req_rsn_c)::text = '996N'::text))
-> Bitmap Heap Scan on scwkclsreqrsnsws (cost=71.78..4443.07 rows=5357 width=8) (actual time=0.012..0.012 rows=1 loops=1)
Recheck Cond: (req_rsn_id = screqrsnsws.req_rsn_id)
-> Bitmap Index Scan on con_scwkclsreqrsnsws_pri (cost=0.00..70.44 rows=5357 width=0) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (req_rsn_id = screqrsnsws.req_rsn_id)
-> Hash (cost=823.09..823.09 rows=4408 width=51) (actual time=3.186..3.186 rows=4401 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 313kB
-> Index Scan using i_scwksmlcls_ek on scwksmlcls (cost=0.00..823.09 rows=4408 width=51) (actual time=0.011..2.002 rows=4401 loops=1)
Index Cond: (wk_sml_cls_id_ek IS NOT NULL)
-> Index Scan using con_scwkmdlcls_pri on scwkmdlcls (cost=0.00..2.17 rows=1 width=37) (actual time=0.005..0.005 rows=1 loops=1)
Index Cond: (wk_mdl_cls_id = scwksmlcls.wk_mdl_cls_id)
Filter: (wk_mdl_cls_id_ek IS NOT NULL)
-> Index Scan using con_scwklrgcls_pri on scwklrgcls (cost=0.00..0.37 rows=1 width=28) (actual time=0.009..0.009 rows=1 loops=1)
Index Cond: (wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id)
Filter: (wk_lrg_cls_id_ek IS NOT NULL)
Total runtime: 3.364 ms

postgresql和oracle的执行计划还真是不一样。

另外还发现有意思的事情,业务上“screqrsnsws.req_rsn_c = scwksmlcls.wk_dept_c”这个是成立的,加入这个条件后语句也能变快,原因是WHERE条件里的"screqrsnsws.req_rsn_c = '996N' "的条件,执行计划里会"scwksmlcls.wk_dept_c = '996N'",内层表的选取数据变小。

EXPLAIN ANALYZE
SELECT
scwksmlcls.wk_cls_c
, scwklrgcls.wk_lrg_cls_nm
, scwkmdlcls.wk_mdl_cls_nm
, scwksmlcls.wk_sml_cls_nm
, scwksmlcls.wk_cls_rmk
FROM
screqrsnsws
INNER JOIN scwkclsreqrsnsws
ON scwkclsreqrsnsws.req_rsn_id = screqrsnsws.req_rsn_id
AND screqrsnsws.req_rsn_id_ek IS NOT NULL
INNER JOIN scwksmlcls
ON scwksmlcls.wk_sml_cls_id = scwkclsreqrsnsws.wk_sml_cls_id
AND screqrsnsws.req_rsn_c = scwksmlcls.wk_dept_c
AND scwksmlcls.wk_sml_cls_id_ek IS NOT NULL
INNER JOIN scwkmdlcls
ON scwkmdlcls.wk_mdl_cls_id = scwksmlcls.wk_mdl_cls_id
AND scwkmdlcls.wk_lrg_cls_id = scwksmlcls.wk_lrg_cls_id
AND scwkmdlcls.wk_mdl_cls_id_ek IS NOT NULL
INNER JOIN scwklrgcls
ON scwklrgcls.wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id
AND scwklrgcls.wk_lrg_cls_id_ek IS NOT NULL
WHERE
screqrsnsws.req_rsn_c = '996N'
AND screqrsnsws.req_rsn_id_ek IS NOT NULL
ORDER BY
scwklrgcls.disp_odr
, scwkmdlcls.disp_odr
, scwksmlcls.disp_odr

QUERY PLAN
Sort (cost=859.96..859.97 rows=1 width=96) (actual time=2.025..2.025 rows=1 loops=1)
Sort Key: scwklrgcls.disp_odr, scwkmdlcls.disp_odr, scwksmlcls.disp_odr
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=0.00..859.95 rows=1 width=96) (actual time=1.050..2.013 rows=1 loops=1)
Join Filter: (scwksmlcls.wk_lrg_cls_id = scwkmdlcls.wk_lrg_cls_id)
-> Nested Loop (cost=0.00..855.66 rows=1 width=79) (actual time=1.041..2.003 rows=1 loops=1)
-> Nested Loop (cost=0.00..851.35 rows=1 width=87) (actual time=1.012..1.974 rows=1 loops=1)
-> Index Scan using con_screqrsnsws_pri on screqrsnsws (cost=0.00..8.68 rows=1 width=9) (actual time=0.015..0.030 rows=1 loops=1)
Filter: ((req_rsn_id_ek IS NOT NULL) AND (req_rsn_id_ek IS NOT NULL) AND ((req_rsn_c)::text = '996N'::text))
-> Nested Loop (cost=0.00..842.67 rows=1 width=88) (actual time=0.995..1.942 rows=1 loops=1)
-> Index Scan using i_scwksmlcls_ek on scwksmlcls (cost=0.00..834.11 rows=2 width=60) (actual time=0.988..1.934 rows=1 loops=1)
Index Cond: (wk_sml_cls_id_ek IS NOT NULL)
Filter: ((wk_dept_c)::text = '996N'::text)
-> Index Scan using con_scwklrgcls_pri on scwklrgcls (cost=0.00..4.27 rows=1 width=28) (actual time=0.004..0.005 rows=1 loops=1)
Index Cond: (wk_lrg_cls_id = scwksmlcls.wk_lrg_cls_id)
Filter: (wk_lrg_cls_id_ek IS NOT NULL)
-> Index Scan using con_scwkclsreqrsnsws_pri on scwkclsreqrsnsws (cost=0.00..4.29 rows=1 width=8) (actual time=0.028..0.028 rows=1 loops=1)
Index Cond: ((req_rsn_id = screqrsnsws.req_rsn_id) AND (wk_sml_cls_id = scwksmlcls.wk_sml_cls_id))
-> Index Scan using con_scwkmdlcls_pri on scwkmdlcls (cost=0.00..4.28 rows=1 width=37) (actual time=0.005..0.006 rows=1 loops=1)
Index Cond: (wk_mdl_cls_id = scwksmlcls.wk_mdl_cls_id)
Filter: (wk_mdl_cls_id_ek IS NOT NULL)
Total runtime: 2.143 ms

为了能大概看懂这执行计划,还特意搜索了一下"postgresql的explain命令详解",那个挺有用。

postgresql遇到的性能问题的更多相关文章

  1. [转帖]PostgreSQL 参数调整(性能优化)

    PostgreSQL 参数调整(性能优化) https://www.cnblogs.com/VicLiu/p/11854730.html 知道一个 shared_pool 文章写的挺好的 还没仔细看 ...

  2. 数据库新秀 postgresql vs mongo 性能PK

    前几天看了一篇文章<High Performance JSON PostgreSQL vs. MongoDB> 发布在Percona Live Europe 2017 作者是<Dom ...

  3. PostgreSQL学习手册 性能提升技巧

    http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 一.使用EXPLAIN:    PostgreSQL为每个查询都生成一个查询 ...

  4. PostgreSQL hstore 列性能提升一例

    PostgreSQL 支持hstore 来存放KEY->VALUE这类数据, 事实上也相似于ARRAY或者JSON类型.  要高效的使用这类数据,当然离不开高效的索引.我们今天就来看看两类不同的 ...

  5. PostgreSQL 参数调整(性能优化)

    昨天分别在外网和无外网环境下安装PostgreSQL,有外网环境下安装的相当顺利.但是在无外网环境下就是两个不同的概念了,可谓十有八折.感兴趣的同学可以搭建一下. PostgreSQL安装完成后第一件 ...

  6. 【转】postgreSQL​之autovacuum性能问题分析(一)

    最近笔者在项目中遇到postgreSQL的性能问题,所以计划在公众号里写一个系列文章去追踪记录这些问题以及分析过程或解决方法. 本文主要是关于postgreSQL的autovacuum的问题.可能很多 ...

  7. benchmark测试PostgreSQL数据库OLTP性能

    1,安装配置PostgreSQL数据库 2,下载地址:http://sourceforge.net/projects/benchmarksql/?source=navbar Required:JDK7 ...

  8. 【转】postgreSQL​之autovacuum性能问题分析(二)

    如上篇文章提到,如果出现了autovacuum的问题,那么这可能是个悲伤的故事.怎么解决? 笔者觉得可以从如下几个方面着手去考虑解决问题,可以避免一些坑.1) 持续观察,是不是autovacuum问题 ...

  9. CentOS7下安装并简单设置PostgreSQL笔记

    为什么是PostgreSQL? 在.NET Core诞生之前,微软平台上最常见的开发组件便是.NET Framework + SQL Server了,但是现在.NET Core终于让跨平台部署成为了现 ...

随机推荐

  1. Office 针式打印机如何调节边距

    1 右击针式打印机,选择"打印机属性"   2 点击"打印机参数设置"选项卡,之前打印出来如果发现上下距离不合适,可以通过调节但也纸页顶距来调整   该参数值可 ...

  2. hdu oj 1285 确定比赛名次

    hdu oj 1285 确定比赛名次 题目: 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  3. .net Core使用Orcle官方驱动连接数据库 C#参考教程 http://www.csref.cn

    .net Core使用Orcle官方驱动连接数据库   最近在研究.net Core,因为公司的项目用到的都是Oracle数据库,所以简单试一下.net Core怎样连接Oracle. Oracle官 ...

  4. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. Android仿微信朋友圈图片查看器

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/40264551 看博文之前,希望大家先打开自己的微信点到朋友圈中去,细致观察是不是发 ...

  6. Android学习笔记-junit单元测试

    我们都知道测试对于程序员来说是必不可少的,所以,做Android程序,也要学会使用junit,这里比着java的junit测试,要稍微复杂一点,需要一些配置,下面饿哦就介绍一下怎样使用junit的测试 ...

  7. SQLServer IP不能登录问题解决

    最近项目项目需要,要在windows2008R2服务器上部署项目,可是客户那边服务器上SqlServer也没有安装,一切都要自己解决,所以我就找了个2008的版本,进行安装,安装过程没有遇到什么问题, ...

  8. 【Android基础】App签名与打包

    签名的意义 1. 为了保证程序开发人员的合法 2. 防止部分人通过使用同样的Package Name(包名)来混淆替换已安装的程序 3. 保证我们每次公布的版本号的一致性(保证签名一致才干升级) 签名 ...

  9. Bootstrap 过渡效果 transition.js源码分析

    前言: 阅读建议:去github下载一个完整dom然后把,本篇代码复制进去然后运行就好了以地址 Bootstrap 自带的 JavaScript 插件的动画效果几乎都是使用 CSS 过渡实现的,那么判 ...

  10. 魏汝盼医学博士 - Judy Zhu Wei, M.D., F.A.C.O.G.

    魏汝盼医学博士 - Judy Zhu Wei, M.D., F.A.C.O.G.         医院(诊所)名称:CAPRI妇产科诊所 妇产科,华人医生,微创妇科手术专科医生,女医生,fountai ...