同事找我优化SQL,同一条SQL语句LIKE过滤条件不同,执行时间差别很多,废话不说安排一下。

LIKE过滤条件执行快的SQL和执行计划:

  1. EXPLAIN ANALYZE
  2. SELECT case_id,
  3. cate_id,
  4. cate_name,
  5. view_url,
  6. proc_ins_id,
  7. create_user_id,
  8. current_user_id,
  9. title,
  10. emergency,
  11. dept_id,
  12. handler_id,
  13. handle_date,
  14. create_date,
  15. end_date,
  16. proc_ins_state,
  17. hint
  18. FROM AAAAAA H
  19. WHERE handler_id = '8feae683-f741-45de-b430-7db24b4f7660'
  20. AND title like '%通报%'
  21. ORDER BY handle_date desc nulls last, emergency DESC;
  22.  
  23. Sort (cost=83260.22..83263.92 rows=1479 width=463) (actual time=203.872..205.642 rows=1750 loops=1)
  24. Sort Key: H.handle_date DESC NULLS LAST, P.emer_level DESC
  25. Sort Method: quicksort Memory: 968kB
  26. -> Gather (cost=12513.91..83182.35 rows=1479 width=463) (actual time=146.637..204.384 rows=1750 loops=1)
  27. Workers Planned: 2
  28. Workers Launched: 2
  29. -> Hash Join (cost=11513.91..69536.90 rows=616 width=452) (actual time=140.984..182.745 rows=583 loops=3)
  30. Hash Cond: (P.cate_id = C.id)
  31. -> Parallel Hash Join (cost=11506.98..69528.32 rows=616 width=408) (actual time=140.808..182.364 rows=583 loops=3)
  32. Hash Cond: (H.proc_ins_id = P.id)
  33. -> Parallel Bitmap Heap Scan on ccccccccccc H (cost=443.78..58432.47 rows=12438 width=156) (actual time=6.527..46.555 rows=10375 loops=3)
  34. Recheck Cond: (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte)
  35. Filter: ((state = 'A'::bpcharbyte) AND (category = 'H'::bpcharbyte))
  36. Heap Blocks: exact=2799
  37. -> Bitmap Index Scan on PROC_INS_HANDLERS_HANDLER_ID (cost=0.00..436.31 rows=29851 width=0) (actual time=7.405..7.405 rows=31125 loops=1)
  38. Index Cond: (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte)
  39. -> Parallel Hash (cost=10935.95..10935.95 rows=10180 width=289) (actual time=132.111..132.112 rows=4266 loops=3)
  40. Buckets: 32768 Batches: 1 Memory Usage: 4480kB
  41. -> Parallel Seq Scan on ddddddddddddd P (cost=0.00..10935.95 rows=10180 width=289) (actual time=0.049..126.563 rows=4266 loops=3)
  42. Filter: ((title)::text ~~ '%通报%'::text)
  43. Rows Removed by Filter: 160050
  44. -> Hash (cost=4.19..4.19 rows=219 width=81) (actual time=0.079..0.080 rows=221 loops=3)
  45. Buckets: 1024 Batches: 1 Memory Usage: 33kB
  46. -> Seq Scan on eeeeeeeeeeeee C (cost=0.00..4.19 rows=219 width=81) (actual time=0.016..0.040 rows=221 loops=3)
  47. SubPlan 1
  48. -> Index Scan using wf_act_instances_PKEY on wf_act_instances (cost=0.43..8.45 rows=1 width=14) (actual time=0.011..0.012 rows=0 loops=1750)
  49. Index Cond: (id = H.act_ins_id)
  50. Planning Time: 1.185 ms
  51. Execution Time: 205.909 ms

LIKE过滤条件执行慢的SQL和执行计划:

  1. EXPLAIN ANALYZE
  2. SELECT case_id,
  3. cate_id,
  4. cate_name,
  5. view_url,
  6. proc_ins_id,
  7. create_user_id,
  8. current_user_id,
  9. title,
  10. emergency,
  11. dept_id,
  12. handler_id,
  13. handle_date,
  14. create_date,
  15. end_date,
  16. proc_ins_state,
  17. hint
  18. FROM AAAAAA H
  19. WHERE handler_id = '8feae683-f741-45de-b430-7db24b4f7660'
  20. AND title like '%表扬%'
  21. ORDER BY handle_date desc nulls last, emergency DESC;
  22.  
  23. Sort (cost=21036.84..21036.85 rows=3 width=463) (actual time=2023.884..2023.948 rows=139 loops=1)
  24. Sort Key: H.handle_date DESC NULLS LAST, P.emer_level DESC
  25. Sort Method: quicksort Memory: 97kB
  26. -> Gather (cost=1449.85..21036.82 rows=3 width=463) (actual time=9.150..2023.615 rows=139 loops=1)
  27. Workers Planned: 2
  28. Workers Launched: 2
  29. -> Nested Loop (cost=449.85..20011.17 rows=1 width=452) (actual time=25.891..2010.559 rows=46 loops=3)
  30. -> Nested Loop (cost=449.71..20010.66 rows=1 width=408) (actual time=25.841..2010.065 rows=46 loops=3)
  31. -> Parallel Seq Scan on ddddddddddddd P (cost=0.00..10935.95 rows=20 width=289) (actual time=0.616..138.214 rows=185 loops=3)
  32. Filter: ((title)::text ~~ '%表扬%'::text)
  33. Rows Removed by Filter: 164131
  34. -> Bitmap Heap Scan on ccccccccccc H (cost=449.71..453.73 rows=1 width=156) (actual time=10.097..10.097 rows=0 loops=556)
  35. Recheck Cond: ((proc_ins_id = P.id) AND (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte))
  36. Filter: ((state = 'A'::bpcharbyte) AND (category = 'H'::bpcharbyte))
  37. Heap Blocks: exact=29
  38. -> BitmapAnd (cost=449.71..449.71 rows=1 width=0) (actual time=10.093..10.093 rows=0 loops=556)
  39. -> Bitmap Index Scan on PUBLIC_ccccccccccc_INDEX_7 (cost=0.00..5.68 rows=166 width=0) (actual time=0.042..0.042 rows=77 loops=556)
  40. Index Cond: (proc_ins_id = P.id)
  41. -> Bitmap Index Scan on PROC_INS_HANDLERS_HANDLER_ID (cost=0.00..436.31 rows=29851 width=0) (actual time=9.495..9.495 rows=31125 loops=556)
  42. Index Cond: (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte)
  43. -> Index Scan using eeeeeeeeeeeee_PKEY on eeeeeeeeeeeee C (cost=0.14..0.50 rows=1 width=81) (actual time=0.007..0.007 rows=1 loops=139)
  44. Index Cond: (id = P.cate_id)
  45. SubPlan 1
  46. -> Index Scan using wf_act_instances_PKEY on wf_act_instances (cost=0.43..8.45 rows=1 width=14) (actual time=0.014..0.014 rows=1 loops=139)
  47. Index Cond: (id = H.act_ins_id)
  48. Planning Time: 1.753 ms
  49. Execution Time: 2024.430 ms

AAAAAA 表是个视图,定义如下:

  1. -----------------+--------------------------------+----------+--------+------+----------+------
  2. case_id | character(36 byte) | | | | extended |
  3. cate_id | character(36 byte) | | | | extended |
  4. CATE_NAME | character varying(100 char) | | | | extended |
  5. VIEW_URL | character varying(1024 char) | | | | extended |
  6. PROC_INS_ID | character(36 byte) | | | | extended |
  7. create_user_id | character(36 byte) | | | | extended |
  8. current_user_id | character(36 byte) | | | | extended |
  9. title | character varying(600 char) | | | | extended |
  10. EMERGENCY | character(1 byte) | | | | extended |
  11. dept_id | character(36 byte) | | | | extended |
  12. handler_id | character(36 byte) | | | | extended |
  13. handle_date | timestamp(3) without time zone | | | | plain |
  14. create_date | timestamp(3) without time zone | | | | plain |
  15. end_date | timestamp(3) without time zone | | | | plain |
  16. PROC_INS_STATE | character(1 byte) | | | | extended |
  17. HINT | character varying(60 byte) | | | | extended |
  18.  
  19. SELECT P.case_id,
  20. P.cate_id,
  21. C.name AS CATE_NAME,
  22. C.url AS VIEW_URL,
  23. P.id AS PROC_INS_ID,
  24. P.create_user_id,
  25. P.current_user_id,
  26. P.title,
  27. P.emer_level AS EMERGENCY,
  28. H.dept_id,
  29. H.handler_id,
  30. H.handle_date,
  31. P.create_date,
  32. P.end_date,
  33. P.state AS PROC_INS_STATE,
  34. ( SELECT wf_act_instances.hint
  35. FROM wf_act_instances
  36. WHERE wf_act_instances.id = H.act_ins_id) AS HINT
  37. FROM ccccccccccc H,
  38. ddddddddddddd P,
  39. eeeeeeeeeeeee C
  40. WHERE H.proc_ins_id = P.id AND H.state = 'A'::bpchar::bpcharbyte AND H.category = 'H'::bpchar::bpcharbyte AND C.id = P.cate_id;

可以看到,两条SQL是除了LIKE模糊查询的过滤条件不一样,其他的写法是完全一致,

where title like '%通报%' 执行时间需要205ms,返回数据 1750 行,

where title like '%表扬%' 执行时间需要2024ms,返回数据 139 行,

正常情况下应该是谓词过滤条件为 '%表扬%' 的SQL语句执行速度更快才是,毕竟返回的数据更少,事实上这个过滤条件比前者慢了10倍。  

前者执行计划:

 后者执行计划: 

通过对比发现后者SQL语句的表关联条件 proc_ins_id = P.id 竟然又 Recheck Cond 一次(回表),而前者的表关联条件是没有进行回表的 Hash Cond: (H.proc_ins_id = P.id),确定找到慢的地方。

增加联合索引优化:

  1. create index idx_ccccccccccc_1_2 on ccccccccccc(proc_ins_id,handler_id);

优化后执行SQL语句:

  1. 优化后执行SQL语句:
  2.  
  3. EXPLAIN ANALYZE
  4. SELECT case_id,
  5. cate_id,
  6. cate_name,
  7. view_url,
  8. proc_ins_id,
  9. create_user_id,
  10. current_user_id,
  11. title,
  12. emergency,
  13. dept_id,
  14. handler_id,
  15. handle_date,
  16. create_date,
  17. end_date,
  18. proc_ins_state,
  19. hint
  20. FROM AAAAAA H
  21. WHERE handler_id = '8feae683-f741-45de-b430-7db24b4f7660'
  22. AND title like '%表扬%'
  23. ORDER BY handle_date desc nulls last, emergency DESC
  24. QUERY PLAN
  25. ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  26. Sort (cost=12129.97..12129.97 rows=3 width=464) (actual time=159.627..162.448 rows=139 loops=1)
  27. Sort Key: H.handle_date DESC NULLS LAST, P.emer_level DESC
  28. Sort Method: quicksort Memory: 97kB
  29. -> Gather (cost=1000.58..12129.94 rows=3 width=464) (actual time=1.069..162.167 rows=139 loops=1)
  30. Workers Planned: 2
  31. Workers Launched: 2
  32. -> Nested Loop (cost=0.58..11104.29 rows=1 width=453) (actual time=1.615..148.219 rows=46 loops=3)
  33. -> Nested Loop (cost=0.43..11103.79 rows=1 width=409) (actual time=1.585..148.059 rows=46 loops=3)
  34. -> Parallel Seq Scan on ddddddddddddd P (cost=0.00..10934.44 rows=20 width=290) (actual time=1.197..145.137 rows=185 loops=3)
  35. Filter: ((title)::text ~~ '%表扬%'::text)
  36. Rows Removed by Filter: 164131
  37. -> Index Scan using idx_ccccccccccc_1_2 on ccccccccccc H (cost=0.43..8.46 rows=1 width=156) (actual time=0.015..0.015 rows=0 loops=556)
  38. Index Cond: ((proc_ins_id = P.id) AND (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte))
  39. Filter: ((state = 'A'::bpcharbyte) AND (category = 'H'::bpcharbyte))
  40. -> Index Scan using eeeeeeeeeeeee_PKEY on eeeeeeeeeeeee C (cost=0.14..0.50 rows=1 width=81) (actual time=0.003..0.003 rows=1 loops=139)
  41. Index Cond: (id = P.cate_id)
  42. SubPlan 1
  43. -> Index Scan using wf_act_instances_PKEY on wf_act_instances (cost=0.43..8.45 rows=1 width=14) (actual time=0.013..0.013 rows=1 loops=139)
  44. Index Cond: (id = H.act_ins_id)
  45. Planning Time: 1.443 ms
  46. Execution Time: 162.906 ms
  47. (21 行记录)
  48.  
  49. EXPLAIN ANALYZE
  50. SELECT case_id,
  51. cate_id,
  52. cate_name,
  53. view_url,
  54. proc_ins_id,
  55. create_user_id,
  56. current_user_id,
  57. title,
  58. emergency,
  59. dept_id,
  60. handler_id,
  61. handle_date,
  62. create_date,
  63. end_date,
  64. proc_ins_state,
  65. hint
  66. FROM AAAAAA H
  67. WHERE handler_id = '8feae683-f741-45de-b430-7db24b4f7660'
  68. AND title like '%通报%'
  69. ORDER BY handle_date desc nulls last, emergency DESC;
  70.  
  71. QUERY PLAN
  72. -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  73. Sort (cost=16733.04..16733.23 rows=73 width=464) (actual time=246.592..252.130 rows=1750 loops=1)
  74. Sort Key: H.handle_date DESC NULLS LAST, P.emer_level DESC
  75. Sort Method: quicksort Memory: 968kB
  76. -> Gather (cost=1000.58..16730.78 rows=73 width=464) (actual time=0.596..250.878 rows=1750 loops=1)
  77. Workers Planned: 2
  78. Workers Launched: 2
  79. -> Nested Loop (cost=0.58..15106.63 rows=30 width=453) (actual time=0.435..228.229 rows=583 loops=3)
  80. -> Nested Loop (cost=0.43..15101.36 rows=30 width=409) (actual time=0.403..224.391 rows=583 loops=3)
  81. -> Parallel Seq Scan on ddddddddddddd P (cost=0.00..10934.44 rows=499 width=290) (actual time=0.062..135.724 rows=4266 loops=3)
  82. Filter: ((title)::text ~~ '%通报%'::text)
  83. Rows Removed by Filter: 160050
  84. -> Index Scan using idx_ccccccccccc_1_2 on ccccccccccc H (cost=0.43..8.34 rows=1 width=156) (actual time=0.021..0.021 rows=0 loops=12797)
  85. Index Cond: ((proc_ins_id = P.id) AND (handler_id = '8feae683-f741-45de-b430-7db24b4f7660'::bpcharbyte))
  86. Filter: ((state = 'A'::bpcharbyte) AND (category = 'H'::bpcharbyte))
  87. -> Index Scan using eeeeeeeeeeeee_PKEY on eeeeeeeeeeeee C (cost=0.14..0.18 rows=1 width=81) (actual time=0.006..0.006 rows=1 loops=1750)
  88. Index Cond: (id = P.cate_id)
  89. SubPlan 1
  90. -> Index Scan using wf_act_instances_PKEY on wf_act_instances (cost=0.43..8.45 rows=1 width=14) (actual time=0.015..0.015 rows=0 loops=1750)
  91. Index Cond: (id = H.act_ins_id)
  92. Planning Time: 1.551 ms
  93. Execution Time: 252.611 ms
  94. (21 行记录)

可以看到,两个谓词过滤条件不同的SQL语句执行时间已经相差无几,在正式环境上创建索引后SQL运行速度有明显提升,本案例已经优化完毕。

kingbase sql 回表优化案例的更多相关文章

  1. (转)减少oracle sql回表次数 提高SQL查询性能

    要写出高效的SQL,那么必须必须得清楚SQL执行路径,介绍如何提高SQL性能的文章很多,这里不再赘述,本人来谈谈如何从 减少SQL回表次数 来提高查询性能,因为回表将导致扫描更多的数据块. 我们大家都 ...

  2. MySQL的索引单表优化案例分析

    建表 建立本次优化案例中所需的数据库及数据表 CREATE DATABASE db0206; USE db0206; CREATE TABLE `db0206`.`article`( `id` INT ...

  3. mysql:如何利用覆盖索引避免回表优化查询

    说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml 17 ...

  4. MySQL索引优化(索引单表优化案例)

    1.单表查询优化 建表SQL CREATE TABLE IF NOT EXISTS `article` ( `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUT ...

  5. MySQL索引优化(索引两表优化案例)

    建表SQL CREATE TABLE IF NOT EXISTS `class` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `card` INT ...

  6. SQL Server表分区案例

    --学习创建表分区脚本/*SQL SERVER 2005中以上版本,终于引入了表分区,就是说,当一个表里的数据很多时,可以将其分拆到多个的表里,大大提高了性能.下面举例子说明之*/ --------- ...

  7. Oracle学习(四)SQL高级--表优化相关(序列、视图等)

    INDEX(索引) 可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到索引,它们只能被用来加速搜索/查询. PS:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引 ...

  8. SQL多表查询案例

    表结构: emp表: dept表: salgrade表: (1)查出至少有一个员工的部门.显示部门编号.部门名称.部门位置.部门人数. SELECT z.*,d.dname,d.loc FROM de ...

  9. SQL单表查询案例

    表(emp)结构 (1)查询部门编号为10中所有经理,部门编号为20中所有销售员,还有即不是经理又不是销售员但其工资大或等于20000的所有员工详细资料. SELECT * FROM emp ; (2 ...

  10. MySQL优化:如何避免回表查询?什么是索引覆盖? (转)

    数据库表结构: create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engin ...

随机推荐

  1. python笔记:第十二章文件

    1.打开文件 位于自动导入的模块IO中,无需手动导入. f = open('D:\M\test.txt') 若文件不存在,则报错 Traceback (most recent call last): ...

  2. Java并发篇:6个必备的Java并发面试种子题目

    线程创建和生命周期 线程的创建和生命周期涉及到线程的产生.执行和结束过程.让我们继续深入探索这个主题: 线程的创建方式有多种,你可以选择适合你场景的方式: 继承Thread类: 创建一个类,继承自Th ...

  3. Linux系统安装CH341驱动

    Linux系统安装CH341驱动 Linux系统(这里以ubuntu20.04为例)本身会自动安装CH340驱动,随着时间的推移,旧版本的驱动已经无法支持当下的CH340模块,所以我们需要重新安装驱动 ...

  4. 关于微信小程序原生组件与uniApp混合开发过程遇到的问题与解决方式

    前言: 在实际开发过程中,尤其是小程序的开发,我们常常会遇到一些在文档中解决不了的问题,在这里,我就浅谈一下我遇到的一些问题 1.小程序的构建框架是uni-app,却突然被要求用原生的微信小程序代码来 ...

  5. 2023-07-31:用r、e、d三种字符,拼出一个回文子串数量等于x的字符串。 1 <= x <= 10^5。 来自百度。

    2023-07-31:用r.e.d三种字符,拼出一个回文子串数量等于x的字符串. 1 <= x <= 10^5. 来自百度. 答案2023-07-31: 大体步骤如下: 1.初始化一个字符 ...

  6. 如何创建Windows 10 虚拟机

    一 ,新建Windows 10 虚拟机 1.1 创建新的虚拟机 1,点击创建新的虚拟机 2,选择典型,点击下一步 3,选择稍后安装操作系统,点击下一步. 4,操作系统选择windwos,版本选着Win ...

  7. Blazor前后端框架Known-V1.2.11

    V1.2.11 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Git ...

  8. 使用kafka自带脚本进行压力测试

    前言 kafka官方自带压力测试脚本: 消费者压力测试:kafka-consumer-perf-test.sh 生产者压力测试:kafka-producer-perf-test.sh 测试节点: 17 ...

  9. 给你安利一款带有AI功能的数据库管理工具

    写在前面 说到数据库管理工具,大家应该不陌生了 小伙伴们应该都用过Navicat.DBever.DataGrip.SQLyog.plsqldeveloper等数据库管理工具 这些工具呢都各自有优缺点. ...

  10. KVM下windows由IDE模式改为virtio模式蓝屏 开不开机

    KVM安装Windows默认使用的是qemu虚拟化IDE硬盘模式,在这种情况下,IO性能比较低,如果使用virtio的方式可以提高虚拟机IO性能. 于是我想将这台虚拟机迁移到openstack中管理 ...