二维码

[性能] ABAP 查询性能提高之索引

Twilight发表于 2014-05-20 16:17Twilight 最后回复于 2014-05-20 16:17 [复制链接] 5976 0

索引简介:

各位应该都知道,我们说到数据库的查询速度优化问题,不得不提到索引,它是提高查询性能的重要方面(当然同时它会影响其它修改类SQL的性能)。通俗的讲,就像我们读一本书不得不有个目录,索引就相当我们每本书的目录,而书中的实际内容就相当我们某个具体的数据表。要在书中查找某部分内容的时候,我们不会一页一页去翻书,而是先从目录中找到相关内容所在页码,然后再按页码去找相关内容,从而大大提高了查找速度。关于各类数据库的索引知识,实在是太多太复杂,在此不敢多说,我们主要来说说SAP概念上的索引。


SAP表索引重要分两种:

1、主索引,它是依据表的主关键字自动建立的(因为一个满足第三范式的数据表都会有一个主关键字,所以每个表都应该有一个主索引,如果主索引丢失,会有相应的错误提示)

2、二级索引,简单的说主索引就是除主索引以外的索引,它与主索引的主要区别就是,主索引表的物理排列次序和表的物理排列次序是相同的。由于这种特性,在查询批量数据的时候,主索引可以按照地址段去表里面取数据,而二级索引可能同样要一个一个地去数据表中取数据,导致利用主索引比利用二级索引查询数据要快得多(当然如果是查询单条记录的话,两者的性能就是一样的)。

在SAP中查看数据表索引的方法:

查看主索引:SE11进入数据字典初始界面——》输入表名点显示——》字段。现在我们看到的主键栏位上打钩的字段就是我们的主键字段,同时依据它建立的默认主索引名称为:00。

查看二级索引:SE11进入数据字典初始界面——》输入表名点显示——》索引。将弹出此表的所有二级索引的列表,然后你可以双击每一行去查看每个索引的详细信息。

以上是索引的一些简单知识,它对我们查询语句中WHERE条件的设计至关重要。


SAP SQL语句优化:

1、 在查询语句的SELECT取字段列表中,我们应该尽量避免用“SELECT *”,而应该取多少字段我们就列多少字段。这样做的理由有三:

一、当使用“SELECT *”的时候,查询在执行的时候是会将“*”解析为相应的字段的,这无疑需要花费时间。

二、大量的无用的字段信息的取出是要占用数据库的DATA CACH空间的(这理所当然的会占用其他有用数据的空间,引起数据置换),大家知道,我们在从数据库中去数据的时候,首先会到缓存中去查找有没有相同的数据,如果有就直接从缓存中取,如果没有则要去读取数据文件,而同样的数据从CACH中取比从数据文件中取大约要快10~100倍。

三、SAP在设计的时候为了提高数据查询性能本身也设计了缓存(SAP的缓存包括公共缓存及用于存储用户特有背景信息的缓存,这方面的内容有时间再和大家详谈),而此处的缓存和数据库的患存类似的是,多余的信息同样会占用空间。并且SAP用户从缓存中取背景数据到用户私有缓存区时,是按照一个固定的大小一部分一部分取的,这样多余的信息无疑会增加SAP用户读取背景信息的次数,增加背景信息转入转出时间,从而降低性能!

2、 WHERE条件中索引(包括主索引和二级索引)限制字段的排列次序,分两种情况:

一、索引字段都在查询的WHERE条件中,此种情况,我们可以不注意限制字段的排列次序,效果都一样,因此不多说。

二、当某个索引中的某些字段在WHERE条件中,而某些又不在时候,我们应该严格按照索引中字段的排列次序来在WHERE条件中安排字段次序,因为数据库它在查找索引表的时候,是严格按照索引次序来在索引表中查询地址信息的。另,当某几个连续的索引字段中的一个不在WHERE条件中的时候,其实此字段后的索引字段对性能的提高已经失去了意义。例如:所以A,它包括A1、A2、A3、A4四个索引字段,当我们在WHERE条件中用到A1、A2、A4,此时A4其实在索引表中查询数据地址段的时候已经不会用到,也就失去了意义(当然限制在具体的数据表中还是有限制性的,只是不能提高性能而已)。

3、 WHERE条件中非索引字段的排列次序。应该将筛选作用大的字段排在右边(专业地讲就是将选择性大的字段放在右边),因为SQL中解析WHERE条件的次序是从右至左的,这样先最大限度地筛选数据,有利于提高数据查询性能。

4、当要进行某列或某几列数据的聚合运算时候,让这中运算在数据库中用聚合函数(SUM、AVG、MAX……)来实现呢,还是先将数据取出来,然后到应用程序中进行运算处理。这就要视情况而定,大量的数据聚合函数运用会极大地影响数据库性能,而传输大量的原始数据到应用程序,在处理会在增加网络的传输量(当数据库服务器和应用服务器不在同一台机器上时)。本人建议应该尽量减少数据层次的运算,因为数据库的性能是会影响整个系统的,而网络传输量大影响的性能可能只影响某个用户(这里没有考虑等待资源的问题)。

5、在WHERE语句中应该尽量避免使用IN关键字,而应该根据具体的情况用LIKE、<>、=等关键字或运算符号去替代它。经验表明,IN关键字的查询性能是最差的。

6、不要循环从数据库中查询数据。即,当你运行两个查询,其中第二个查询要以第一个查询的结果为条件的时候,你不应该先将第一个查询的数据放入一个内表,然后循环这个内表,去执行第二个查询。而应该先在缺少第一个内表数据的情况下,将第二个内表的数据取出来,然后再在应用程序中去匹配处理。这样会大大地减少访问数据库的次数,减少读取IO,特别是数据库服务器和应用服务器不在同一台机器上时,更是万分必要。

7、用SELECT语句取数据的时候,应该让SELECT后面跟的字段次序与你要放入的内表的次序一样。比如你定义了内表
  1. BEGIN OF ITAB,
  2. A1 AS ..
  3. A2 AS ..
  4. A3 AS ..
  5. A4 AS ..
  6. END OF ITAB.
复制代码

那你在查询语句中也应该对应为SELECT A1 A2 A3 A4 INTO ITAB FROM……..。

以上SQL语句中的一些简单原则,当然具体问题还得具体分析,所以懂的每种数据SQL优化器的原理,及SQL语句的执行计划,然后灵活运用才是最重要的。

并且由于现在我们系统刚上线,系统性能比较好,暂时体现不出优化的显著效果,但长时间运行后效果就会就会非常明显,正如我们不能很容易地区分一秒钟和两秒钟的差别,但很能很容易区分一个小时和两个小时的差别一样。

习惯决定风格,所以各位在让自己程序实现功能的同时,更应该注意程序的可读性、健壮性及可用性。一个劣质性能的程序在大系统中必然会被淘汰,因为它不仅自己运行速度慢还会影响其它程序的运行性能。
回复

使用道具 举报

快速回帖

本版积分规则
您需要登录后才可以回帖 登录 | 注册有礼

快速回复 返回顶部 返回列表