随着数据量以惊人速度不断增长,数据库管理系统将继续关注性能问题。本文主要介绍一种名为函数索引(functional index)的性能调优技术。根据数据库使用情况的统计信息创建并使用函数索引,可以显著提升SELECT 查询的性能。通过本文了解如何在IBM Informix Dynamic Server 中创建和使用函数索引并最大限度提升查询性能。
简介
在选择数据库管理系统(DBMS)时,性能是一个关键的考虑因素。在执行SELECT、INSERT、UPDATE 和 DELETE 操作时,很多因素都会对性能产生影响。这些因素包括:
持久性数据存储的速度和大小
数据存储结构
数据访问方法
随着数据集不断变大,查询性能愈发变得重要。
通常,使用索引可以改善查询性能。索引将数据库中的行位置与一组有序数据子集和/或数据派生物关联在一起。索引可以减少DBMS 在执行查询时检查的行(或 元组)数量,从而获得性能增益。有时,仅通过搜索索引即可完成查询,而不需要从表中取回任何元组(tuple)。例如,如果您在列 c1 中建有索引,并且发出查询select c1 from t1 where c1 < 10 ,那么索引中包含了可以满足查询的所有信息。
有趣的是,ANSI SQL 标准并没有说明如何创建、实现或维护索引。因此,数据库供应商可以按照自己的方式自由地实现索引。
本文讨论了 Informix Dynamic Server 的函数索引特性。要理解本文涉及的概念,您需要熟悉基本的数据库术语和概念,例如模式、表、行、列、索引和可扩展性。还需了解 Informix Dynamic Server (IDS) 的基本配置以及如何启动和停止服务器、如何使用 ONCONFIG 文件进行配置。此外,还需熟悉基本的 SQL 命令以及如何使用 dbaccess 对服务器执行 SQL 命令。
本文的目的是帮助您理解函数索引的定义以及使用。此外,您还将了解如何创建和使用函数索引,以及在创建函数索引之前需要考虑的一些问题。
函数索引的优势
索引按照某种顺序保存列值。函数索引对列中的数据进行转换并按照顺序保存转换后的值。
假设某个表中保存了一个企业的员工名称,并且需要保留名称的大小写形式。那么,如果查询需要执行大小写不敏感的搜索(如下所示),则必须转换数据:
SELECT * FROM t1 WHERE toUpper(name) LIKE 'ANTHONY % HOPKINS';
如果没有为名称建立索引,那么 DBMS 将执行全表扫描并对每个元组(tuple)的 name 列应用 toUpper 函数。要确定元组(tuple)是否满足查询,必须调用 toUpper 函数。当表非常大或者大量会话发出这种类型的查询时,性能将会有所下降。
避免调用 toUpper 函数的一种方法是在表中同时保存大小写混合的名称和大写名称。应用程序查询大小写不敏感的列:
SELECT * FROM t1 WHERE ucname like 'ANTHONY % HOPKINS';
如果没有为 ucname 创建索引,DBMS 仍然执行全表扫描,但是不会对数据进行进一步处理来判断其是否满足查询。尽管这样做改善了性能,但并不是理想的解决方案,因为表非常大,而且所有需要操纵或访问数据的应用程序必须包括处理 ucname 的逻辑。
改善查询性能的一种更好的方法是对 name 创建函数索引:
CREATE FUNCTION toUpper( name VARCHER(100) ) RETURNS VARCHAR(100)
WITH (NOT VARIANT);
RETURN upper( name );
END FUNCTION;
CREATE INDEX ucnameIndex ON t1 ( toUpper(name) );
当执行这种查询时,DBMS 可以使用函数索引判断哪些元组元组(tuple) 满足查询。DBMS 只获取并返回这些满足查询的元组(tuple),如下面的清单所示:
SELECT * FROM t1 WHERE toUpper(name) LIKE 'ANTHONY % HOPKINS';
DBMS 将自动管理函数索引以及不需要包含逻辑来管理大写形式数据的应用程序。通过使用 INSERT、UPDATE 和 DELETE 操作对索引进行更新,DBMS 能够确保索引始终与表数据一致。
接下来将深入讨论如何创建和使用函数索引,以及如何生成和检验查询计划,并提供具体的示例。