技术开发 频道

达梦函数与表达式索引

  【IT168 文档】从DM6.0开始,达梦数据库新增了一个很重要的特性:function-based index(简称FBI)。数据库开发人员在SQL语句调优的过程中遇到的一个很常见的问题就是,如何优化那些在WHERE子句中使用了函数的语句。因为在以前,在WHERE子句中使用函数会使在这个表上创建的索引无法利用,从而难以提升高这个语句的性能。但是用户现在可以通过建立函数索引在查询优化的过程中直接使用预先计算好的表达式值,同时函数索引的建立也增加了使用索引范围扫描的可能性,这些都可以用来提高查询效率。例如:

create table person(id int,name varchar(10),intro varchar(200));
create index ind_name on person(name);
explain
select * from person where upper(name)='JOHN';
执行计划:
#RSET:
[1, 1, 0];
#CSEK:
[1, 1, 0]; INDEX33555476(person), FULL_SCAN

  在上面的SQL语句中,虽然我们在person表的name字段上建立了索引,这个索引仍然是用不上的,这是因为我们建的索引针对的是列name,而不是经过upper函数加工后的表达式值。通过执行计划,我们就可以很清楚的了解这一点:索引ind_name并没有被用上,最终是通过全表扫描得到查询结果。如果这个表的数据非常大的话,这会消耗大量的时间。我们再看看建立函数索引后的情况:

create index fbi_ind_name on person(upper(name));
explain
select * from person where upper(name)='JOHN';
执行计划:
#RSET:
[0, 0, 0];
#CSEK(SECOND):
[0, 0, 0]; fbi_ind_name(person), INDEX_EQU_SEARCH

  从这个执行计划我们可以看到,这次达梦数据库不是对全表进行扫描,而是通过索引进行查询,因为达梦的优化器是基于成本的,所以这里会知道函数索引的存在。

  我们来看几个例子,对比一下使用函数索引优化前后的性能:

  场景一:TABLE FBI_T01(C INT),表中有100万数据

 

  场景二:TABLE FBI_T02(C1 VARCHAR(100), C2 VARCHAR(100)),表中有100万数据

 

  场景三:TABLE FBI_T03(C1 INT, C2 INT),表中100万数据

  通过上面三个场景的性能测试,我们可以很清楚认识到函数索引对于性能提升的作用。

  目前,DM6的函数索引存在以下约束和限制:

  (1)函数索引只支持单表达式索引,不支持由多个表达式组成的复合索引。但表达式可以由多列组成;

  (2) 表达式里面不允许出现大字段列;

  (3)不支持不确定性函数(如:sysdate()函数,每次查询得到的结果都不一样;

  (4) 不支持分区表上建立函数索引;

  (5)不支持建立分区函数索引;

  (6)表达式字符串的长度限制:理论上不能超过2000个字符。

0
相关文章