SQL语句分为五类:
1.SELECT语句(SELECT)
2.DML语句(UPDATE,DELETE,INSERT)
3.DDL语句(CREATE DROP ALTER)
4.DCL语句(GRANT REVOKE)
5.TCL语句(COMMIT ROLLBACK)
这里需要强调的是SELECT语句并不属于DML语句的范畴。由于业务系统中往往书写的SELECT语句较为复杂,而DML语句一般较为简单,之前我在工作中的调优工作大部分是指的SELECT语句的调优,而忽略了对DML语句的调优。虽然DML语句本身非常的简单,但是当并发增大、DML操作表的数据量较大就会导致性能的急剧下降。
执行DML语句会用到UNDO表空间和在线Redo日志文件,如果执行大量的DML并发操作,这两部分所在磁盘的IO会变得非常的大,当磁盘的IO接近100%的时候,DML操作就会变得非常的慢,这个时候系统可能会处在非常缓慢的状态。
对于操作系统而言,如果
安装系统所在的磁盘IO被撑满,例如SWAP频繁的发生交换导致IO一直处于100%左右的状态,这个时候连接系统是非常慢的,CPU会大量的消耗用于等待IO,运行在操作系统上的
数据库或应用也会随着操作系统IO的满负荷运行而变得非常的慢。同样的道理,执行DML语句会消耗UNDO表空间和在线Redo日志所在磁盘的IO,如果这两部分磁盘IO接近100%,那么整个数据库执行DML语句会变得非常的缓慢。如果UNDO和REDO所在磁盘和操作系统在一个磁盘系统中,操作系统也会变得非常慢,如果跟数据文件在一个磁盘系统中,SELECT语句也会变慢。从这个角度来说,UNDO和Redo应该放在与数据库文件不同的磁盘系统上,并有独立的磁盘IO,相互之间不应该受到影响。
对于大表的DELETE或UPDATE操作要非常的谨慎,在业务运行期间尽量不要对大表执行大数据量的UPDATE和DELETE操作,对大表打数据量的DELETE操作可能会导致UNDO所在磁盘系统IO非常的高,也可能会导致REDO所在磁盘的IO非常的高,这样会阻止其他会话或事务的DML语句的执行。并且即时你终止了客户端的运行相关的操作依然在后台进程,即便KILL SESSION也是没有效果的,最终只有结束操作系统进程。对于这样的情况我们应该采用分区表来解决大表数据的删除和更新问题,表分区能为数据的
管理带来巨大的便利。并且尽量要在系统使用最不频繁的时候来执行大数据量的更新或删除操作。
综上所述,对于DML语句的调优我们有如下的经验:
1.UNDO和Redo应该放在最快的磁盘系统上,并且应该与其它数据存储处于不同的磁盘系统,最好它们之间也处于不同的磁盘系统,避免相互影响。可以通过为UNDO表空间创建属于不同磁盘系统的数据文件来分担UNDO表空间承受的IO压力。在线Redo日志文件可以放在经过条带化的存储系统中,提高IO性能。
2.UNDO表空间和在线Redo日志应该足够的大,减少由于空间的问题导致的额外磁盘IO操作。
3.对于大数据量的表应该作为分区表来处理,便于UPDATE和DELETE执行的效率。
4.应当避免在高峰期间对大表进行打数据量的DELETE和UPDATE操作。
以上的规则能够有效地提高并发情况下DML语句执行的效率,减少DML语句的执行对其它操作带来的影响。同时为了提高排序等工作的效率同样应该设置足够大的临时表空间大小。
UNDO和Redo就好比操作系统的SWAP一样,它只是个临时的区域,并不需要太大的空间,但它是非常重要的,衡量UNDO和REDO最重要的指标就是IO性��。所以,对这种不需要太大空间,但对IO要求很高的空间来说,数据库部署方案尤为重要,应该根据系统实际的情况来进行考虑。