Oracle数据库中有多种创建表的方式。如可以通过复制其他表的方式来建立数据库表;而可以利用Select查询语句从其他数据库对象中查询数据并生成新的数据库表。但是如果利用这些形式来建立表的话(即在建立表的时候同时在新表中插入数据),如果数据比较多,则这个建表的速度会比较慢。这主要是因为默认情况下,建立表、插入数据等动作都会先写入到重做日志文件中,然后再建立相关的表并插入记录。也就是说,相当于数据库系统这个动作要操作两遍。这就降低了数据库建表的速度。当记录越多,这速度就会越慢。
Nologging选项就是让数据库在插入大量数据或者进行其他复杂操作时不写重新操作,而是直接建立表或者插入数据。但是Nologging参数的使用也会受到一定的限制。
一、 Nologging使用的限制。
Nologging选项使用的限制主要体现在两个方面,一是并不是所有的语句都支持这个选项;二是其生效的时间跟数据库的归档模式相关。如数据库管理员可能需要一次性更新某个表中上百万条的纪录。此时管理员可以通过Update语句来更新。但是因为这个更新动作会同时写入到重做日志当中。所以当记录比较多(或者表之间关联更新)的时候,执行Update更新语句会花费比较长的时间。此时能否可以采用Nologging语句来提高更新性能呢?答案是否定的,因为Update更新语句不支持Nologging这个选项。故数据库管理员在采用这个参数时,需要知道那些语句支持这个语句,哪些语句不支持。
另外Nologging参数的生效还跟数据库的运作模式相关。通常情况下数据库运作模式有归档日至模式与非归档日志模式的差异。在非归档日志模式下,数据库将不会对重做日志文件进行归档操作。而在归档模式下,数据库系统将对重做日志文件进行归档操作。即在日志发生切换时,系统进程先要等待归档进程将下一个重做日志文件归档完毕后才写入重做日志文件,覆盖其中的重做日志文件。Nologging选项是否生效,还直接跟这两个操作模式有关。根据笔者的了解,同样是采用了Nologging选项,相对来说在非归档模式下要比在归档模式下效果明显一点。
再者数据库工程师要明白一个问题,就是direct insert也可以成批插入数据。不过这个插入跟insert插入有区别。前者在插入数据的时候,不会写重做日志。而后者常规插入的话,则会写入重做日志中。此时,nologgin选项对于他们来说是不起作用的。故如果数据库工程师需要插入大量的数据并且要提高插入的速度,则要注意此时nologging选项对于insert语句不起作用。此时数据库工程师只能够通过direct insert语句来提高插入效率。因为这条语句默认情况下是不会写入重做日志的。
二、 Nologging的典型应用。
虽然Nologging选贤在使用时受到不少的限制,但是在实际工作中其仍然是一个很有用的工具,特别是数据库在初始化的时候其特别有效。具体的来说在如下几种情况中利用这个参数可以提高操作效率。
一是当数据库管理员通过CREATE TABLE AS SELECT(即数据库管理员可以通过查询语句来创建表)语句创建表时,笔者建立在语句中加入Nologging选项。特别是当记录比较多的时候。此时加入这个参数,可以避免在创建表的过程中产生过多的重做记录。如此的话,不仅可以节省重做日志文件的存储空间,而且还能够加快表的创建速度。一举多得,值得数据库管理员去尝试。
二是在创建大表的时候也适宜采用这个参数。通常情况下,Nologging参数更加适合于创建大表时采用。在创建大表(同时需要插入大量数据)时加上这个参数,相对于创建小表来说,能够获得更加明显的速度提升。
同时数据库工程师需要注意,执行Update更新语句时,这个参数会失效。故有时候数据库管理员会发现一个奇怪的问题,更新一百万条记录比插入同样的一百万条记录速度还慢。这很可能是因为在插入数据的时候采用了Nologging参数或者是采用direct insert语句。他们不会在插入数据的同时写入重做日志。那么如何才能够提高update语句的执行效率呢?这是一个很复杂的问题,三言两语也说不清楚。简单的来说,在update更新语句中,是不能够通过这个参数来限制其重做日志的操作。不过可以通过其他方式来提高其执行效率。如可以把所需要修改数据的数据表中索引等先暂时停用掉,等到数据更新完成后再启用。这就可以比较明显的提高数据更新效率。