一、调优目标

SQL 调优的整体目标是使用最优的执行计划,使IO以及CPU代价最小。调优主要关注下列方面:

·表扫描

如果计划中对某大表使用了全索引扫描,那么需要关注该表是否存在某个查询条件使得过滤后可以淘汰至少一半的数据量。通过添加相应的索引,全索引扫描可能被转换为范围扫描或等值查找。

·连接操作的顺序和类型

多表连接时,尽可能找到一种能使中间结果保持最小的连接顺序。

对于给定的一个连接或半连接,DM 可以用 HASH 连接、嵌套循环连接、索引连接或者是归并连接实现。通过分析表的数据量大小和索引信息,SQL 调优目标是选择最适宜的操作符。对半连接而言,HASH 连接还可细分为左半 HASH 和右半 HASH。用户可以通过始终对数据量小的一侧建立 HASH 来进行调优。

·分组操作

分组操作往往要求缓存所有数据以找到属于同一组的所有数据,在大数据量情况下这会带来大量的 IO。应该检查 SQL 查询和表上索引信息,如果可以利用包含分组列的索引,执行计划就会使用排序分组从而不用缓存中间结果。

二、确定高负载的 SQL

打开监控开关(ENABLE_MONITOR=1、MONITOR_TIME=1)

通过查询动态视:

V$LONG_EXEC_SQLS(显示最近 1000 条执行时间较长的 SQL 语句),如SELECT * FROM V$LONG_EXEC_SQLS;

V$SYSTEM_LONG_EXEC_SQLS(显示服务器启动以来执行时间最长的20 条 SQL 语句)如SELECT * FROM V$SYSTEM_LONG_EXEC_SQLS;

三、开发有效的 SQL 语句

1.避免使用 OR 子句

如果OR子句都是对同一列进行过滤,用户可以考虑使用IN VALUE LIST的过滤形式。

SELECT ... WHERE CITY = 'SHANGHAI' OR CITY = 'WUHAN' OR CITY = 'BEIJING';

调整为

SELECT ... WHERE CITY IN( 'SHANGHAI','WUHAN','BEIJING');

2.避免使用困难的正则表达式

例如:a LIKE 'L%'可以优化为 a>='L' AND a<'M',这样就可以用到 a 上的索引。即使没有索引,转换后的比较也更快。

3.灵活使用伪表(SYSDUAL)

首先可以利用伪表进行科学计算,执行语句 SELECT 3*4 FROM SYSDUAL,则可以得

到结果 12;

其次,在某些方面使用 SYSDUAL 可提高效率。例如:查询过程中要判断表 t1 中是否有满足 condition1 条件的记录存在,可执行以下语句:

SELECT COUNT(*) INTO x FROM t1 WHERE condition1;

然后根据变量 x 的取值来判断。但是当 t1 非常大时该语句执行速度很慢,而且由于不

知道 SELECT 返回的个数,不能用 SELECT *代替。事实上这个查询可以利用伪表来完成:

SELECT 'A' INTO y FROM SYSDUAL

WHERE EXISTS (SELECT 1 FROM t1 WHERE condition1);

判断 y 值,如等于'A'则 T1 中有记录。调整后的语句执行速度明显比上一句高。

另外,在 DM 的语法里是可以省略 FROM 子句的,这时系统会自动加上 FROM SYSDUAL。

因此前面的科学计算例子可以简化为 SELECT 3*4;

4.SELECT 项避免“*”

除非用户确实要选择表中所有列,否则 SELECT *这种写法将让执行器背上沉重的负荷。

因为每一列的数据不得不自下往上层层向上传递。不仅仅如此,如果用户查询的是列存储表,

那么列存储所带来的 IO 优势将损耗殆尽。

任何时候,用户都要了解表结构和业务需求,小心地选择需要的列并一一给出名称,避

免直接用 SELECT *。

5.避免功能相似的重复索引

索引并非越多越好。抛开优化器面对众多索引逐一试探所耗费的时间不谈,如果表上增

删改操作频繁,那么索引的维护将会成为大麻烦,尤其是函数索引的计算开销更不能忽略

6.使用 COUNT(*)统计结果行数

如果对单表查询 COUNT(*)且没有过滤条件,那么 DM 优化器会直接读取相关索引中存

储的行数信息,加以回滚段中其他事务插入或删除元组的行数修正,迅速地给出最终结果而

避免对实际数据的读取。相比之下,COUNT(列名)会对数据进行读操作,执行效率远低于

COUNT(*)。

即使查询中含有过滤条件,由于 DM 特有的批处理方式,COUNT(*)依旧快于其他写法。

这是因为 COUNT(*)无需取得行的具体值而仅仅需要行数这一信息。

需要额外说明的是,COUNT(*)会将 NULL 值计算在内而 COUNT(列名)是不包含 NULL

值的,因此用户要结合应用场景决定是否可以使用 COUNT(*)。

7.使用 EXPLAIN 来查看执行计划

在查询语句或者插入、删除、更新语句前增加 EXPLAIN 关键字,DM 将显示其执行计划

而无需实际执行它。查阅 V$SQL_NODE_NAME 表中每个操作符的含义,用户可以很方便且

直观地了解数据如何被处理及传递。如果启用了统计信息收集,那么对照执行计划和对动态

视图 V$SQL_NODE_HISTORY,V$SQL_NODE_NAME 的查询结果,用户就可以知道在实际执 行中每一个操作符执行的时间,进而找出性能瓶颈。

8.UNION UNION ALL 的选择

UNION 和 UNION ALL 的区别是前者会过滤掉值完全相同的元组,为此 UNION 操作符

需要建立 HASH 表缓存所有数据并去除重复,当 HASH 表大小超过了 INI 参数指定的限制时 还会做刷盘。

因此如果应用场景并不关心重复元组或者不可能出现重复,那么 UNION ALL 无疑优于

UNION。

9.优化 GROUP BY ... HAVING

GROUP BY 最常见的实现有 HASH 分组(HAGR)和排序分组(SAGR)。前者需要缓存中

间结果;如果用户在 GROUP BY 的列上建立索引,那么优化器就会判断并可能使用上该索引,这时的 GROUP BY 就会变为 SAGR。

HAVING 是分组后对结果集进行的过滤,如果过滤条件无关集函数操作,可以考虑将过滤条件放在 WHERE 而不是 HAVING 中。

10.使用优化器提示(HINT

利用经验对优化器的计划选择进行调整,HINT 是 SQL 调整不可或缺的一步。

相详细说明参见《DM8系统管理员手册》

四、查看执行计划

1. 使用EXPLAIN 命令查看执行计划

示例:

explain

select dept.dept_name, emp.* FROM departments dept

left JOIN dept_emp de ON de.dept_no = dept.dept_no

left JOIN employees emp ON emp.emp_no = de.emp_no;

2.使用EXPLAIN FOR 命令查看执行计划

explain  for

select dept."dept_name", emp.* FROM "DMTEST"."departments" dept

left JOIN "DMTEST"."dept_emp" de ON de."dept_no" = dept."dept_no"

left JOIN "DMTEST"."employees" emp ON emp."emp_no" = de."emp_no";

3.执行计划中常见的操作符解释

常见的操作符有:

NSET2:结果集

PRJT2:投影,,用于选择表达式项的计算。

CSCN2 :聚集索引扫描

SSCN :直接使用二级索引进行扫描

SSEK2 :二级索引数据定位

CSEK2 :聚集索引数据定位

BLKUP2 :定位查找

SLCT2:关系的―选择‖(select)运算,用于查询条件的过滤。

SORT: SORT是做排序操作时使用到的操作符。

HAGR:HASH AGR操作,是最基础的分组方式,对于没有优化条件的分组语句,一般都会按这种方式进行分组。

SAGR: SORTED AGR操作,同一分组的数据按照顺序取出。

NEST LOOP INNER JOIN(嵌套循环连接) :最基础的连接方式,将一张表的一个值与另一张表的所有值拼接,形成一个大结果集,再从大结果集中过滤出满足条件的行。

HASH JOIN(哈希连接):没有索引的情况下,大多数连接的处理方式,将一张表的连接列做成HASH表,另一张表的数据向这个HASH表匹配,满足条件的返回。

INDEX JOIN(索引连接): 将一张表的数据拿出,去另外一张表上进行范围扫描找出需要的数据行,需要右表的连接列上存在索引。

MERGE JOIN(归并连接):两张表都扫描索引,按照索引顺序进行归并。

  • 查看ET

ET是达梦自带的系统存储过程,能统计SQL每个操作符的时间花费,从而定位到有性能问题的操作,指导我们去优化;

达梦ET默认未启用,设置启动以下三个参数可以启用ET(ENABLE_MONITOR、MONITOR_TIME和MONITOR_SQL_EXEC);

其中,ENABLE_MONITOR和MONITOR_TIME默认已开启,如果未开启可以使用如下方法开启:

SP_SET_PARA_VALUE(1,‘ENABLE_MONITOR’,1);

SP_SET_PARA_VALUE(1,‘MONITOR_TIME’,1);

MONITOR_SQL_EXEC为会话级动态参数,可以设置只针对当前会话开启:

SF_SET_SESSION_PARA_VALUE(‘MONITOR_SQL_EXEC’,1);

执行SQL语句,我们会看到一个执行号,直接点这个执行号,即可调用ET;

在知道执行号的情况下,也可以这样使用ET CALL ET(124571)

ET结果说明:

OP: 操作符

TIME(us): 时间开销,单位为微秒

PERCENT: 执行时间占总时间百分比

RANK: 执行时间耗时排序

SEQ: 执行计划节点号

N_ENTER: 进入次数

达梦学习社区地址:https://eco.dameng.com

达梦数据库SQL调优,查看执行计划、ET相关推荐

  1. ORACLE SQL调优之执行计划与隐藏参数_complex_view_merging

    最近,赤峰windows 版的11.2.0.3的oracle数据库出现一条sql语句执行非常慢,需要1天的时间还出不来,但是观察服务器的IO和CPU都是很空闲,并且将 该sql语句涉及的对象全部导出, ...

  2. SQL Server性能调优之执行计划深度剖析 第二节 执行计划第一次实践

    SQL Server性能调优之执行计划深度剖析 第二节 执行计划第一次实践 前言:自从上一篇文章发出之后,收到了很朋友的关注.很多朋友要求多多实践,而不是纯粹的理论.确实,从打算出这个系列开始,我就本 ...

  3. 数据库SQL调优的几种方式(转)

    在项目中,SQL的调优对项目的性能来讲至关重要,所有掌握常见的SQL调优方式是必不可少的,下面介绍几种常见的SQL的调优方式,供借鉴. 一.创建索引 要尽量避免全表扫描,首先应考虑在 where 及 ...

  4. 【与达梦同行】达梦数据库SQL去掉sort

    SQL优化是一个比较复杂的事情,想要做好优化一要靠扎实的技术功底,二要靠丰富的实践经验,这里来谈一下SQL优化中的sort优化问题. 在之前的优化经验中,错误的任务只要结果集不大,含有order by ...

  5. 达梦数据库SQL学习

    数据来源于达梦数据库安装实例时的示例库DMHR 一 分组函数 分组函数做用于一组数据.并对于一组数据返回一个值 常见的分组函数:(聚合函数) AYG.COUNT.MAX.MIN.SUM... sele ...

  6. 达梦数据库SQL日志分析工具Dmlog的使用

    1.使用条件 运行环境预先安装Java环境:支持liunx和windows系统运行. 说明:推荐使用java1.8版本,linux最小化安装最少要安装打印服务组件,windows下不支持java1.6 ...

  7. 达梦数据库-SQL优化之HINT-平坦化处理

    1.HINT之OUTER_JOIN_FLATING_FLAG (1).解释: Flag of indicating whether outer join will be flattened. 对左外连 ...

  8. Oracle数据库sql调优

    最近做的一个项目涉及到大数据量的数据表查询.数据表总量在7亿-20亿左右,以主键建立全局唯一索引,分区策略是hash分区+范围分区,很大部分情况下查询条件命中记录数超过万条,单次返回前XX条记录.在调 ...

  9. 达梦数据库sql优化实践2

    Sql执行过程中,对有索引的列上使用隐式类型转换或函数都会造成索引失效的情况,需要特别注意. 原sql语句如下 SELECT TAB1.RECORDID , TAB1.F_CENTRAL_ID TAB ...

最新文章

  1. 美国一大型数据中心将24h由光伏+储能供电
  2. JavaScript语言中文参考手册.chm
  3. Android 横竖屏切换时 Dialog 布局自适应
  4. 工作总结13:vue官网封装组件
  5. ReactJs 第四章组件组件props
  6. sql timestep 秒数后6位_excel中,如何截取身份证号后6位?前4位?或者中间8位?...
  7. Scrapy相关命令
  8. openmv探索_2_追踪单颜色
  9. SRIO学习笔记之SRIO简介与Xilinx SRIO ip核例程详解
  10. 【干货】如何紧跟未来的设计趋势:15 个让你永远不过时的资源
  11. ios中为视图添加圆角
  12. 2017年终总结——恍恍惚惚又一年
  13. tree traversal (树的遍历) - inorder traversal (中序遍历)
  14. NISP-SO网络安全运维是什么?安全运维工程师
  15. php蓝奏云网盘源码,蓝奏云网盘打开目录/上传/下载源码
  16. TinyOS总体介绍
  17. Json字符串转对象和转List集合操作(json-lib版本)
  18. ctfshow—Node.js漏洞总结
  19. python刷今日头条访问量_Python 自动刷博客浏览量实例代码
  20. IBM实习日记——6.16-6.18

热门文章

  1. sqoop和flume的区别
  2. 计算机动画_3dsmax的使用(四)
  3. CTFShow-MISC篇详细Wp(部分)
  4. tgw介绍和股票历史日线数据程序化下载——量化数据中台系列(四)
  5. ESP8266 Arduino 串口监视器输出乱码原因
  6. 采购管理系统(Java+SSH+mysql)
  7. mysql创建定时任务执行存储过程
  8. [200724]什么才是高速固态硬盘?
  9. 基于facenet的实时人脸检测
  10. 安装 yarn (Windows)