开发基础 报表教程 数据字典 对话编程 表单打印 增强出口 SAP接口 S/4 HANA
实战案例 实战笔记 资料下载 CRM
问答互助 会员分享 俱乐部 广告区
论坛指南、建议和投诉
Twilight发表于 2014-05-20 16:17Twilight 最后回复于 2014-05-20 16:17 [复制链接] 5976 0
使用道具 举报
Twilight
管理员
发表回复 回帖后跳转到最后一页
各位应该都知道,我们说到数据库的查询速度优化问题,不得不提到索引,它是提高查询性能的重要方面(当然同时它会影响其它修改类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后面跟的字段次序与你要放入的内表的次序一样。比如你定义了内表
那你在查询语句中也应该对应为SELECT A1 A2 A3 A4 INTO ITAB FROM……..。
以上SQL语句中的一些简单原则,当然具体问题还得具体分析,所以懂的每种数据SQL优化器的原理,及SQL语句的执行计划,然后灵活运用才是最重要的。
并且由于现在我们系统刚上线,系统性能比较好,暂时体现不出优化的显著效果,但长时间运行后效果就会就会非常明显,正如我们不能很容易地区分一秒钟和两秒钟的差别,但很能很容易区分一个小时和两个小时的差别一样。
习惯决定风格,所以各位在让自己程序实现功能的同时,更应该注意程序的可读性、健壮性及可用性。一个劣质性能的程序在大系统中必然会被淘汰,因为它不仅自己运行速度慢还会影响其它程序的运行性能。