达梦数据库的SQL调优(二)

避免使用OR子句
OR子句在实际执行中会被转换为类似于UNION的查询。如果某一个OR子句不能利用上索引则会使用全表扫描造成效率低下,应避免使用。
使用OR子句对一个表中同一列进行过滤,可以使用IN VALUE LIST的过滤形式来代替OR子句。
SQL> SELECT SALARY FROM DMHR.EMPLOYEE WHERE DEPARTMENT_ID=1001 OR DEPARTMENT_ID=1002 OR DEPARTMENT_ID=1003;
达梦数据库的SQL调优(二)
SQL> SELECT SALARY FROM DMHR.EMPLOYEE WHERE DEPARTMENT_ID IN (1001,1002,1003);
达梦数据库的SQL调优(二)
避免使用困难的正则表达式
在SQL语言中,LIKE关键字支持通配符匹配,含通配符的表达式称为正则表达式。有的正则表达式可以自动优化为非匹配的。
A LIKE ‘L%’ 可以优化为a>=’L’ AND a <’M’,这样可以用到a上的索引。即使没有索引,转换后的比较也更快。
A LIKE ‘LM_’ 可以转化为a>=’LM’ AND a<’LN’ AND a LIKE ‘LM_’
虽然仍然包含着通配符匹配,但大大缩小了匹配的范围。
困难的正则表达式指的是开头和结尾都为通配符的正则表达式,如’L%’、’%L’,优化器没有办法缩小它们的匹配范围,也不可能用到索引而必须使用全表扫描。因此要尽可能避免这样的正则表达式。
如果仅仅是开头为通配符,用户可以在列a上建立REVERSE(a)这样一个函数索引,利用函数索引反转待匹配项从而使用函数索引进行范围扫描。
灵活使用伪表(SYSDUAL)
伪表是一个虚拟表,用来构成select的语法规则。使用伪表来查看当前用户
SQL> select user from sysdual;
达梦数据库的SQL调优(二)
SELECT项避免’
SELECT 这种写法会让执行器的负荷很大,如果查询列存储表,那么列存储带来的IO优势将耗尽。
避免功能相似的重复索引:索引并非越多越好
使用COUNT(
)统计结果行数
如果对单表查询COUNT(
)且没有过滤条件,DM优化器会直接读取相关索引中存储的行数信息,加以回滚段中其他事务插入或删除元组的行数修正,迅速地给出最终结果而避免对实际数据的读取。
COUNT()无需取得行的具体值而仅仅需要行数这一信息。
COUNT(
)会将NULL值计算在内而COUNT(列名)是不包含NULL值的。
使用UNION和UNION ALL
union和union all的区别是前者会过滤掉值完全相同的元组,为此union操作符需要建立HASH表缓存所有数据并去除重复,当HASH表大小超过了INI参数指定的限制时会做刷盘。
优化GROUP BY … HAVING
GROUP BY最常见的实现有HASH分组(HAGR)和排序分组(SAGR)。前者需要缓存中间结果;如果用户在GROUP BY的列上建立索引,那么优化器就会判断并可能使用上该索引,这时的GROUP BY就会变为SAGR。
HAVING是分组后对结果集进行的过滤,如果过滤条件无关集函数操作,可以将过滤条件放在WHERE而不是HAVING中。DM优化器会判断并自动转换部分等效于WHERE的HAVING子句,但显式地给出最佳SQL语句会让优化器工作更好。