详细介绍查询优化技术在现实系统中的运用

详细介绍查询优化技术在现实系统中的运用,第1张

详细介绍查询优化技术在现实系统中的运用,第2张

数据库是管理信息系统的核心,基于数据库的联机事务处理(OLTP)和联机分析处理(OLAP)是银行、企业、政府等部门最重要的计算机应用之一。从大多数系统的应用实例来看,查询操作在各种数据库操作中所占的比重,查询操作所依据的SELECT语句是SQL语句中开销较大的语句。举个例子,如果数据量积累到一定程度,比如某银行的账户数据库表信息积累到几百万甚至上千万条记录,往往需要几十分钟甚至几个小时才能扫描一遍整个表。如果采用比全表扫描更好的查询策略,查询时间往往可以减少到几分钟,可见查询优化技术的重要性。

在应用项目的实施中,笔者发现很多程序员在使用一些前端数据库开发工具(如PowerBuilder、Delphi等)时,只注重华丽的用户界面,而不注重查询语句的效率。)开发数据库应用,导致开发的应用系统效率低下,资源浪费严重。因此,如何设计高效合理的查询语句非常重要。结合应用实例和数据库理论,介绍了查询优化技术在实际系统中的应用。

分析问题

很多程序员认为查询优化是DBMS(数据库管理系统)的任务,和程序员写的SQL语句关系不大,这是错误的。一个好的查询计划往往可以将程序性能提高几十倍。查询计划是用户提交的一组SQL语句,查询计划是优化后生成的一组语句。DBMS的查询计划处理过程如下:对查询语句进行词法和语法检查后,将语句提交给DBMS的查询优化器。优化器完成代数优化和访问路径优化后,预编译模块对语句进行处理,生成查询计划,然后在适当的时候提交给系统进行处理和执行,最后将执行结果返回给用户。在实际数据库产品的高版本中(如Oracle、Sybase等。),采用基于成本的优化方法。这种优化可以根据从系统字典表中获得的信息来估计不同查询计划的成本,然后选择更好的计划。虽然目前的数据库产品在查询优化方面已经做得越来越好,但是用户提交的SQL语句才是系统优化的基础。很难想象一个原本糟糕的查询计划经过系统优化后会变得高效,所以用户写的语句质量至关重要。我们暂且不讨论系统做的查询优化。下面重点介绍改善用户查询计划的解决方案。

解决问题

以关系数据库系统Informix为例,介绍改进用户查询计划的方法。

1.索引的合理使用

索引是数据库中一种重要的数据结构,其根本目的是提高查询效率。目前,大多数数据库产品采用由IBM首先提出的ISAM索引结构。应正确使用索引,其使用原则如下:

●索引建立在频繁连接但未指定为外键的列上,而那些不频繁连接的列由优化器自动索引。

●对经常排序或分组的列建立索引(即group by或order by操作)。

●对条件表达式中常用的差异值较多的列建立检索,不对差异值较少的列建立索引。例如,employee表的“性别”列中只有“男性”和“女性”两个不同的值,因此不需要建立索引。如果建立索引,不但不能提高查询效率,反而会严重拖慢更新速度。

●如果有多个要排序的列,可以在这些列上建立复合索引。

●使用系统工具。比如Informix数据库有一个tbcheck工具,可以检查可疑索引。在一些数据库服务器上,由于频繁的操作,索引可能会失败或者读取效率会降低。如果使用索引的查询莫名其妙地变慢,可以尝试用tbcheck工具检查索引的完整性,必要时修复。另外,当数据库表更新大量数据时,删除和重建索引可以提高查询速度。

2.避免或简化排序

应该简化或避免对大表的重复排序。当索引可以用来以适当的顺序自动生成输出时,优化器就避免了排序的步骤。以下是一些影响因素:

●要排序的一列或几列没有包含在索引中;

●group by或order by子句中的列顺序与索引顺序不同;

●排序的列来自不同的表。

为了避免不必要的排序,需要正确的建立额外的索引,合理的合并数据库表(虽然有时候可能会影响表的标准化,但是为了提高效率还是值得的)。如果排序是不可避免的,那么应该尽量简化,比如缩小排序列的范围。

3.消除对大型表行数据的顺序访问。

在嵌套查询中,对表的顺序访问可能会对查询效率产生致命的影响。例如,使用顺序访问策略,一个具有三个嵌套层的查询,如果每个层查询1000行,那么这个查询将查询10亿行数据。避免这种情况的主要方法是对连接的列进行索引。比如两个表:学生表(学号,姓名,年龄…)和选课表(学号,课程号,成绩)。如果要连接两个表,应该在“学生ID”的连接字段中建立一个索引。

您还可以使用union来避免顺序访问。尽管所有检查列上都有索引,但是某些形式的where子句会强制优化器使用顺序访问。以下查询将对orders表强制执行顺序操作:

SELECT * FROM orders WHERE(customer _ num = 104且order_num>1001)或order_num=1008

尽管索引是基于customer_num和order_num构建的,但是在上面的语句中,优化器仍然使用顺序访问路径来扫描整个表。因为此语句要检索一组分隔的行,所以应该将其更改为以下语句:

SELECT * FROM customer _ num = 104且order_num>1001的订单

联盟

orders WHERE order _ num = 1008的订单

这样,您可以使用索引路径来处理查询
4。避免相关的子查询。

如果列的标签同时出现在主查询和where子句的查询中,则在主查询中的列值更改后,很可能必须再次查询子查询。嵌套的查询层次越多,效率越低,所以要尽量避免子查询。如果子查询不可避免,请在子查询中筛选出尽可能多的行。

5.避免困难的正式表达

MATCHES和LIKE关键字支持通配符匹配,技术上称为正则表达式。但是这种匹配特别耗时。示例:select * from客户,其中邮政编码为“98 _ _”

即使在zipcode字段上建立了索引,在这种情况下,仍然采用顺序扫描。如果将语句改为SELECT * FROM CUSTOMER WHERE ZIP CODE >“98000”,则在执行查询时将使用索引进行查询,显然会大大提高速度。

此外,避免非起始子串。例如,语句select * from customer where zip code[2,3]>“80”在where子句中使用了非起始子字符串,因此该语句将不使用索引。

6.使用临时表来加速查询。

对表的子集进行排序并创建临时表有时可以加快查询速度。它有助于避免多次排序操作,还可以通过其他方式简化优化器的工作。例如:

SELECT客户名称,rcVBles.balance,…其他列

来自客户,接收

其中客户标识=客户标识

和rcvblls.balance>0

和客户邮政编码>“98000”

按客户名称排序

如果该查询要执行多次,您可以找出所有未付款的客户并将其放在一个临时文件中,然后按客户名称对其进行排序:

SELECT客户名称,rcvbles.balance,…其他列

来自客户,接收

其中客户标识=客户标识

和rcvblls.balance>0

按客户名称排序

转入临时客户余额

然后按以下方式在临时表中查询:

SELECT * FROM cust_with_balance

其中邮政编码>“98000”

临时表的行数比主表少,物理顺序是要求的顺序,减少了磁盘I/O,所以查询工作量可以大大减少。

注意:临时表不会反映主表创建后的修改。当主表中的数据被频繁修改时,注意不要丢失数据。

7.用排序代替非顺序访问。

非顺序磁盘访问是最慢的操作,表现在磁盘访问臂的来回移动。SQL语句隐藏了这种情况,使得我们在编写应用程序时,很容易编写出需要访问大量非顺序页面的查询。有时,用数据库的排序能力代替非顺序访问可以改善查询。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 详细介绍查询优化技术在现实系统中的运用

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情