· 中文版     · English Version

中小型图书馆信息网

学海拾贝 书林漫步

首页  >  本站指南  >  技术交流 > 

提高数据库性能

  发布时间:2011/3/31 15:55:14 , 浏览次数:617

  说明:本文是侧重于开发和设计的。以后有时间的话,从DBA的角度出发,分析不同的DBMS的自身配置,不同的DBMS与操作系统、多个应用程序的负载均衡等。

一、硬件:
          
  数据库服务器很重要,你是选择联想、浪潮、还是IBM还是其它,服务器你的配置如何,这些都要根据你的实际需要。当然也可以选择一台普通的PC机作为服务器,只要能满足你的需求。
       
  1、内存。如果内存太小,则加大了从磁盘读取和存储中间结果等数据的频度,降低了性能;当然,内存泄漏导致内存不断减少。

  2、中央处理器。如果其处理慢的话,会造成等待和其它资源的浪费。
       
  3、硬盘。指物理硬盘或磁盘阵列,而非只是逻辑分区。其读取的速度会影响性能,其大小会影响数据的存储量,会导致宕机。

二、操作系统与DBMS:

  1、不同的操作系统之间的差异;

  2、不同的数据库管理系统性能各有优劣,选择合适数据库管理系统。

  是选择桌面数据库,如:My Sql 、ASA等,还是选择大型数据,如:oracle、DB2、SQL Server、Sybase等,还是选择国产数据库,如:达梦、大金仓、神州等。数据库的选型非常重要,因为要考虑目前的需要,还要考虑以往项目和以后的 升级等。
        
  是选择以行和列二维结构存储数据的关系型数据库还是选择文件数据库还是其它,这主要考虑数据的用途、数据的类型、数据从存储到数据库再到展示整个过程是否需要复杂的转换。当然,令人期待的后关系型数据库管理系统还存在理论上。

  当然还要受到操作系统、硬件等制约,比如asa在Linux平台上是不支持的,而My sql则可以,当然My sql是免费的。比如Oracle对内存要求比较高。

三、架构:
       
  1、使用集中式数据库还是分布式数据库;使用大型数据库和桌面数据的结合还是其它;各种数据对象使用方式;数据库的表结构的设计,数据库结构及表结构不合 理的就太不上其它优化措施;选择是桌面数据库、桌面应用程序定时向总数据库中上传数据,还是没有桌面应用程序,所有的客户端都是通过浏览器来访问中央的站 点和中央数据库,这取决于每个客户有没有良好的网络环境、带宽和中央服务器的性能。
       
  2、一个服务器上实例的个数,各实例之间的负载均衡,实例与操作系统其它服务之间的负载均衡和内存分配;配置虚拟内存,比如将其配置为物理内存的1.5 倍。
       
  3、IO是数据库的最大瓶颈,减少没有必要的对db的访问,如果有些数据是用户不需要的而且要经常使用的数据,可以放到方便快速存取的地方而不是每次都从数据库取;
       
  4、将数据处理放到数据库服务其上还是其它服务器上。一种是在数据库中将原始的数据经过复杂的运算整理,输出;另一种是数据中只输出原始的最基本的数据, 输出后的web服务器或者其它服务器上进行整理,最后展示或者前台使用,把数据、日志、索引放到不同的I/O设备上,增加读取速度。
       
  5、在整个架构中,建议使用存储过程而不是向db发送sql语句,因为前者是预编译的,灵活和高效。
       
  6、对数据库操作时间的划分,分时间段上传数据,避免在上传的同时进行大量的数据抽取的job和trigger等,避免插入的时候进行大量的查询和深度计算,job与性能,快照、分发复制;不要将日常业务数据和ETL、OLTP等放到一起。

  7、将事务放到数据库去保证事务的一致性,还是放到应用程序各自的数据库提供者中去处理,还是放到数据库提供者之上统一处理。使用专用的数据提供者而不是odbc或者oledb,这样可以充分利用数据的性能;事务尽可能简短。
        
  8、外部因素。如其他应用程序系统访问本系统或者本数据库时,也要考虑其优劣。安全也会影响数据库的性能。
        
  9、用户可以接受的响应时间是多少,如果经过各种处理还不能满足,那就要限制查询或者操作数据库的条件,每次处理少量的数据。对查询取消、查询超时进行处理,否则会一直将db服务器拖下去。
        
  10、对其它前端开发工具的功能的充分利用。如缓冲池,那么在不同的地方写的同样的sql语句,应该字符串是一样的。

  11、DB Server 和APPLication Server 分离;OLTP(On-line Transaction Processing)和OLAP(On-Line Analytical Processing)分离 ;把数据、日志、索引放到不同的I/O设备上,增加读取速度。
         
  12、分布式分区视图可用于实现数据库服务器联合体,实现dblink功能;应用程序设计为可避免死锁;将一个大数据库分程几个小数据库,在应用程序中去访问,分担数据库服务器的负载。

四、数据库对象:

  1、表。稀疏矩阵、表的数据类型的宽度 。
         
  2、临时表。如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定;如果是oracle,还要决定是使用基于会话的临时表,还是基于事务的临时表;是使用正式表和会话ID结 合来存储中间数据,还是使用临时表。
         
  3、索引。唯一、顺序、空值;插入与查询的均衡,此消彼张;将索引放到不同的磁盘上;插入数据时,也可已让索引失效,等插入完了之后在将索引的enable置为True。
         
  4、主键。插入数据时,如果有唯一聚簇索引的话,数据库会根据你的唯一聚簇索引进行物理排序,如果唯一聚簇索引不合适,在牺牲了插入速度的代价下,并不会 提高数据的检索速度,因此,创建唯一聚簇索引时要考虑你的通常数据检索的条件、以及检索时的排序,最好索引的顺序和检索数据的条件一致,比如:在你的表 中,有(日报日期,客户,商品)这样的唯一聚簇索引,那检索数据的时候写:where 日报日期between p_bdate and p_edate and 客户= P_客户 and 商品 like P_商品 || '%' ,按照跟索引一致的顺序来检索,会提高效率。
         
  5、分区表。如果你经常要查询固定时间段的数据,可以建立分区表。比如每一个月的数据放到一个分区表中,这样,你如果查询某月的数据时,会很大的提高查询速度。
         
  6、表空间(如果是oracle等)。合理规划表空间,提高数据库相应速度。比如:将索引、主键放到一个表空间中、将基础数据放到一个表空间中、将业务数 据放到一个表空间中、将临时表放到一个表空间等。当然,如果在ms sql server中,可以通过规划数据库文件来实现,但是很少这么做。
         
  7、视图。视图只是逻辑结构,通常使用视图来过滤某些固定的数据,也可以实现分布式数据的查询;当然,使用视图时要考虑效率,如果两个大表关联,那查询速 度是很满的,所以这种情况下建议不要使用视图,而是使用临时表。当然,一般情况下,视图是只读的,但是在oracle中还有物化视图,物化视图有数据操纵 功能。
         
  8、约束。一种是在数据库上完整的建立各种约束,当然,这些约束会降低数据库的相应速度,如,表间外键、表的某一列上的约束;当然,在实际项目中,可能是 通过前端程序去控制各种约束;如果第三方要访问数据库的话,都是不允许直接访问数据库而是通过服务等方式,所以不存在约束问题。
         
  9、充分利用数据库的特有对象,如特有函数,这样比自己写的一般效率要高,但是同时要考虑跨数据库平台时的移植所需要的工作量。
         
  10、系统临时数据库文件或者临时表空间,其是放中间操作结果的,将其数据库放在除用户数据库所使用的磁盘之外的磁盘上,提高io的性能。其中,要注意初始 值、增长步长和最大值的设置,如果步长不是根据实际情况设置的,那么频繁的扩展会降低数据库的性能,如果最大值不加限制的,要考虑会不会用光磁盘上所有的 空间。
         
  11、修改修改数据库的配置参数;如果是oracle的话,主要是调整内存(SGA和PGA)

  12、重建索引、收缩数据和日志都会提高数据库的性能。

五、SQL语句:
        
  结构化查询语言的语法很简单,但是将其用好不是一件容易的事,第三方sql优化工具要谨慎使用。
        
  1、对笛卡尔积、游标、循环要谨慎使用。可以使用临时表或者其它方法。如果数据量很少、可以预期的数据时使用

  2、存储过程、函数、包、触发器等尽量不要超过1000行,之间调用不要复杂;

  4、并发时语句的顺序造成表的死锁。

  5、避免全表扫描。

  6、嵌套、递归、子查询的深度。
       
  7、充分使用临时表、表变量等而不是正式表,主要是为了减少IO;oracle中临时表的机制比较好,在语句块中创建和drop临时表会消耗很多资源的;select into是不记log的,与creat table + insert不同。

  8、尽量少用动态sql,因为其跟踪不方便,后期的维护也不方便。

  9、避免大表联合查询。
              
  10、where条件的先后顺序,这会影响数据量和查询的效率。ORACLE采用自下而上的顺序解析WHERE子句,先过滤掉大表的数据,再进行关联,可以提高查询速度,当然,要考虑主数据表,不要为了提高速度而滤掉了本该查询到的数据。
              
  11、FROM:ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名。

  12、select:select count(1) from t_1;select count(c_1) from t_1;select count(*) from t_1中,最后一个效率最低,当然,前两个要考虑是否有空值;select c_1,c_2 from t_1、select * from t_1中可能前者效率高一些,看你有没有必要返回那么多的列。

  13、没有必要的order by、group by、distinct,因为其是需要占用很大的内存。

  14、减少对复杂case when的使用。
              
  15、between、>=,<=、>,<这三对中,效率依次降低;IN和EXISTS;在海量查询时尽量少用格式转换;IN和 OR会使索引失效,自查询中的NOT in 和in 根据自查询中的数据量确定.避免在索引列上使用计算,使用直连或者exists或者in而不是distinct。
              
  16、索引失效,引起全表扫面。where中的条件的第一个字符为'%',索引会失效,='b%'则不会失效;!=或<>、IS NULL或IS NOT NULL、IN ,NOT IN; LIKE ‘%L%’,=’L’,而‘L%’不会失效;where中索引列进行函数或者表达式运算。
              
  17、尽量是用数值型而不是字符串型,在查询和连接中,字符串需要逐个比较,而数值型只要一次就够了。

  18、union all 比union效率高;相对union,minus、intersect 效率比较高一些。

  19、使用 between 代替in。如:between 0 and 1 与in(0,1) 效率是不一样的

  20、使用NOT EXISTS来代替NOT IN。当然,如果在in里面,把其和外面关联起来的话,效率比单纯的in要高。

  21、其它。比如:union中,字段的宽度;单行自查询中返回多行。对锁也要谨慎使用。

六、其它:

  1、合理清理日志,清理垃圾数据,导出导入可以减少碎片。
              
  2、借助于其它辅助工具分析性能瓶颈,如windows的任务管理器的性能显示、sql server的事件跟踪器、Toad、pl/sql developer、数据库管理系统中自带的跟踪功能对sql语句等进行分析。

 

;

首页  -  公告  -  本站指南  -  新闻中心  -  名馆展示  -  区域检索  -  下载中心  -  留言板  -   后台管理

地址:浙江省杭州市下城区潮王路东方豪园俊豪阁 电话:0571-81956312 传真:0571-81956329

版权所有 ©1999-现在 杭州蓝博计算机有限公司 浙ICP备14028990号 浙公网安备33010602013611