达梦数据库系列—44.SQL调优

avatar
作者
猴君
阅读量:0

目录

SQL优化思路

1、定位慢sql

2、SQL分析方法

2.1 执行计划

2.2 ET 工具

2.3 dbms_sqltune 工具

3、SQL语句优化

3.1 索引

3.2 SQL语句改写

3.3 表设计优化

3.4 表的连接方式

3.5 HINT

4、统计信息


SQL优化思路

1、定位慢sql

待优化的SQL大致可分为两类:

1、SQL 执行时间在十几秒到数十秒之间,但执行频率不高,此类 SQL 对数据库整体性能影响并不大,可以放到最后进行优化。

2、SQL 单独执行时间可能很快,在几百毫秒到几秒之间,但执行频率非常高,甚至达到每秒上百次,高并发下执行效率降低,很可能导致系统瘫痪,此类 SQL 是优化的首要对象。

定位慢sql的两种方法:

  1. 开启跟踪日志,见“日志总结-SQL日志”
  2. 通过系统视图查看,见“常用SQL-sql相关”

2、SQL分析方法

2.1 执行计划

达梦数据库系列-40.执行计划

2.2 ET 工具

ET 功能默认关闭,可通过配置 INI 参数中的 ENABLE_MONITOR=1、MONITOR_SQL_EXEC=1 开启该功能。

--两个参数均为动态参数,可直接调用系统函数进行修改

SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);

SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);

--会话级别修改只在当前会话生效

SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',1);

--关闭 ET

SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',0);

SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',0);

执行 SQL 语句后,客户端会返回 SQL 语句的执行号。单击执行号即可查看 SQL 语句对应的 ET 结果。

如果没有图形界面,调用存储过程可返回相同结果。

  • OP: 操作符
  • TIME(us): 时间开销,单位为微秒
  • PERCENT: 执行时间占总时间百分比
  • RANK: 执行时间耗时排序
  • SEQ: 执行计划节点号
  • N_ENTER: 进入次数

2.3 dbms_sqltune 工具

使用前提:建议会话级开启参数 MONITOR_SQL_EXEC=1

ALTER SESSION SET 'MONITOR_SQL_EXEC' = 1;

<执行待优化SQL>

select DBMS_SQLTUNE.REPORT_SQL_MONITOR(SQL_EXEC_ID=>1213701) from dual;

3、SQL语句优化

3.1 索引

索引存储结构

从B*树中访问每个叶子节点的成本都是h次IO,索引的访问效率只跟B*树的高度有关系。

以下场景可考虑创建索引:

  • 仅当要通过索引访问表中很少的一部分行(1%~20%)。
  • 索引可覆盖查询所需的所有列,不需额外去访问表。

组合索引的顺序:

  •  最优先把等值匹配的列放最前面,范围匹配的放后面
  •  其次把过滤性好的列放前面,过滤性差的放后面
  •  查询时组合索引只能利用一个非等值字段

存在下列情况将导致无法使用索引:

  • 条件列不是索引的首列
  • 条件列上有函数或计算
  • 存在隐式类型转换
  • 如果走索引会更慢

建立索引的原则:

  • 建立唯一索引。唯一索引能够更快速地帮助我们进行数据定位;
  • 为经常需要进行查询操作的字段建立索引;
  • 对经常需要进行排序、分组以及联合操作的字段建立索引;
  • 在建立索引的时候,要考虑索引的最左匹配原则(在使用 SQL 语句时,如果 where 部分的条件不符合最左匹配原则,可能导致索引失效,或者不能完全发挥建立的索引的功效);
  • 不要建立过多的索引。因为索引本身会占用存储空间;
  • 如果建立的单个索引查询数据很多,查询得到的数据的区分度不大,则考虑建立合适的联合索引;
  • 尽量考虑字段值长度较短的字段建立索引,如果字段值太长,会降低索引的效率。

3.2 SQL语句改写

优化 GROUP BY

在 GROUP BY 之前过滤掉不需要的内容

--优化前

SELECT JOB,AVG(AGE) FROM TEMP GROUP BY JOB HAVING JOB = 'STUDENT' OR JOB = 'MANAGER';

--优化后

SELECT JOB,AVG(AGE) FROM TEMP WHERE JOB = 'STUDENT' OR JOB = 'MANAGER' GROUP BY JOB;

用 EXISTS 替换 DISTINCT

--优化前

SELECT DISTINCT USER_ID,BILL_ID FROM USER_TAB1 D,USER_TAB2 E WHERE D.USER_ID= E.USER_ID;

--优化后

SELECT USER_ID,BILL_ID FROM USER_TAB1 D WHERE EXISTS(SELECT 1 FROM USER_TAB2 E WHERE E.USER_ID= D.USER_ID);

用 WHERE 子句替换 HAVING 子句

用 UNION ALL 替换 UNION

用 TRUNCATE 替换 DELETE

用 EXISTS 替换 IN、用 NOT EXISTS 替换 NOT IN

3.3 表设计优化

水平分区表

见“分区表”

全局临时表

事务型临时表

创建指定临时表是事务级的,每次事务提交或回滚之后,表中所有数据都被删除

CREATE TEMPORARY TABLE TEMP_COMM (C1 INT,C2 INT,C3 DATETIME) ON COMMIT DELETE ROWS;

会话型临时表

创建指定临时表是会话级的,会话结束时才清空表;

CREATE TEMPORARY TABLE TEMP_SESS (C1 INT,C2 INT,C3 DATETIME) ON COMMIT PRESERVE ROWS;

3.4 表的连接方式

达梦数据库系列-41.表连接方式

3.5 HINT

达梦数据库系列-43.HINT

4、统计信息

达梦数据库系列-39.统计信息详解

达梦技术社区:达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!