HelloDBA [中文]
Search Internet Search HelloDBA
  Oracle Technology Site. email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com Add to circle  acoug  acoug 

NULL or NOT NULL --- NOT NULL constraint impacts on execution plan and performance

[中文]

Author:  fuyuncat

Source:  www.HelloDBA.com

Date:  2011-07-21 08:01:37

Share to  Twitter Facebook GMail Blogger Orkut Google Bookmarks Sina Weibo QQ Renren Tieba Kaixin Douban Taobao

NULLABILITY is an important property of column. However, many designers do not care naught for this property. In most scenarios, except primary key columns, all columns are not specified nullbility. By default, it's means nullable.

Actually, it's an importent factor impacting optimizer choosing execution plan. Let's build below table to further describe this issue.

SQL代码
  1. HELLODBA.COM>create table t_test1 tablespace DEMO as select * from dba_objects;  
  2.   
  3. Table created.  
  4.   
  5. HELLODBA.COM>alter table T_TEST1 add constraint T_TEST1_PK primary key (OBJECT_ID) using index  tablespace DEMOTSINX;  
  6.   
  7. Table altered.  
  8.   
  9. HELLODBA.COM>update t_test1 set SUBOBJECT_NAME=OBJECT_NAME where SUBOBJECT_NAME is null;  
  10.   
  11. 32072 rows updated.  
  12.   
  13. HELLODBA.COM>commit;  
  14.   
  15. Commit complete.  
  16.   
  17. HELLODBA.COM>desc t_test1  
  18.  Name          Null?    Type  
  19.  ---------------------------------------------------------------------------------------------------------------------------------  
  20.  OWNER         NOT NULL VARCHAR2(30)  
  21.  OBJECT_NAME   NOT NULL VARCHAR2(30)  
  22.  SUBOBJECT_NAME         VARCHAR2(30)  
  23.  OBJECT_ID     NOT NULL NUMBER  
  24.  DATA_OBJECT_ID         NUMBER  
  25.  OBJECT_TYPE            VARCHAR2(19)  
  26.  CREATED       NOT NULL DATE  
  27.  LAST_DDL_TIME NOT NULL DATE  
  28.  TIMESTAMP              VARCHAR2(19)  
  29.  STATUS                 VARCHAR2(7)  
  30.  TEMPORARY              VARCHAR2(1)  
  31.  GENERATED              VARCHAR2(1)  
  32.  SECONDARY              VARCHAR2(1)  
  33.  LIO                    NUMBER  

Where clause predication evaluation

In the table T_TEST1, subobject_name actually does not contain NULL values, and there isn't NOT NULL constraint on it. We execute below SQL to query the number of NULL value in this column (zero of course).

SQL代码
  1. HELLODBA.COM>select * from t_test1 where SUBOBJECT_NAME is null;  
  2.   
  3. no rows selected  
  4.   
  5. Execution Plan  
  6. ----------------------------------------------------------  
  7. Plan hash value: 1883417357  
  8.   
  9. -----------------------------------------------------------------------------  
  10. | Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)| Time     |  
  11. -----------------------------------------------------------------------------  
  12. |   0 | SELECT STATEMENT  |         |     1 |    96 |    45   (0)| 00:00:46 |  
  13. |*  1 |  TABLE ACCESS FULL| T_TEST1 |     1 |    96 |    45   (0)| 00:00:46 |  
  14. -----------------------------------------------------------------------------  
  15.   
  16. Predicate Information (identified by operation id):  
  17. ---------------------------------------------------  
  18.   
  19.    1 - filter("SUBOBJECT_NAME" IS NULL)  
  20.   
  21. Statistics  
  22. ----------------------------------------------------------  
  23.           0  recursive calls  
  24.           0  db block gets  
  25.         665  consistent gets  
  26.           0  physical reads  
  27.           0  redo size  
  28.        1048  bytes sent via SQL*Net to client  
  29.         374  bytes received via SQL*Net from client  
  30.           1  SQL*Net roundtrips to/from client  
  31.           0  sorts (memory)  
  32.           0  sorts (disk)  
  33.           0  rows processed  

We find it involved Full Table Scan (we will discuss impact on index in following part). We can not the plan and performance changed after we add NOT NULL constraint on it.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify SUBOBJECT_NAME not null;  
  2.   
  3. Table altered.  
  4.   
  5. HELLODBA.COM>select * from t_test1 where SUBOBJECT_NAME is null;  
  6.   
  7. no rows selected  
  8.   
  9. Execution Plan  
  10. ----------------------------------------------------------  
  11. Plan hash value: 4146611218  
  12.   
  13. ------------------------------------------------------------------------------  
  14. | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |  
  15. ------------------------------------------------------------------------------  
  16. |   0 | SELECT STATEMENT   |         |     1 |    96 |     0   (0)|          |  
  17. |*  1 |  FILTER            |         |       |       |            |          |  
  18. |   2 |   TABLE ACCESS FULL| T_TEST1 | 47585 |  4461K|    45   (0)| 00:00:46 |  
  19. ------------------------------------------------------------------------------  
  20.   
  21. Predicate Information (identified by operation id):  
  22. ---------------------------------------------------  
  23.   
  24.    1 - filter(NULL IS NOT NULL)  
  25.   
  26.   
  27. Statistics  
  28. ----------------------------------------------------------  
  29.           0  recursive calls  
  30.           0  db block gets  
  31.           0  consistent gets  
  32.           0  physical reads  
  33.           0  redo size  
  34.        1048  bytes sent via SQL*Net to client  
  35.         374  bytes received via SQL*Net from client  
  36.           1  SQL*Net roundtrips to/from client  
  37.           0  sorts (memory)  
  38.           0  sorts (disk)  
  39.           0  rows processed  

The execution plan adds a FITLER before Full Table Scan, with an expression (NULL IS NOT NULL), whose result is FALSE. Hence, child operation of FILTER actually is not performed. Correspondingly, CR in performance statistics data is 0.

The reason of why optimizer added such FILTER, is because optimizer refers to the NOT NULL constraint to evaluate WHERE clause when perform Query Transformation. If the resutl is evaluated as FALSE, it will add such FITLER to avoid high-cost operations. From 10053 trace file, we notice the evaluation impact on cost estimation.

SQL代码
  1. Cdn, Cost adjusted (to ~ 0) as where clause evalutes to FALSE  
  2. Final - All Rows Plan:  Best join order: 1  
  3.   Cost: 0.0000  Degree: 1  Card: 1.0000  Bytes: 4568160  
  4.   Resc: 0.0000  Resc_io: 0.0000  Resc_cpu: 0  
  5.   Resp: 0.0000  Resp_io: 0.0000  Resc_cpu: 0  

NOT NULL constraint impact on index choosing

As we know, B*Tree index will not contain NULL keys. That is to say, records with NULL values in all indexed columns will not be built in the index. It also means that table records do not full map to index records if there is no NOT NULL constraint.

Now, we remove the NOT NULL constraint on subobject_name and index it.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify subobject_name null;  
  2.   
  3. Table altered.  
  4.   
  5. HELLODBA.COM>create index t_test1_subo_idx on t_test1(subobject_name) compute statistics;  
  6.   
  7. Index created.  

Then execute below query to obtain 10 records with smallest subobject_name. To make it more effecient, we want to get the first 10 ROWIDs from index, which has be sorted by subobject_name, then access table to fetch data by ROWID.

SQL代码
  1. HELLODBA.COM>select owner,object_name,subobject_name from t_test1 t1, (select /*+index(t t_test1_subo_idx)*/rowid rid from t_test1 t where rownum<=10order by subobject_name) v where t1.rowid=v.rid;  
  2.   
  3. OWNER                          OBJECT_NAME                    SUBOBJECT_NAME  
  4. ------------------------------ ------------------------------ ------------------------------  
  5. SYS                            ICOL$                          BBB  
  6. SYS                            I_USER1                        BBB  
  7. SYS                            CON$                           BBB  
  8. SYS                            UNDO$                          BBB  
  9. SYS                            I_PROXY_ROLE_DATA$_1           BBB  
  10. SYS                            I_OBJ#                         BBB  
  11. SYS                            PROXY_ROLE_DATA$               BBB  
  12. SYS                            I_IND1                         BBB  
  13. SYS                            I_CDEF2                        BBB  
  14. SYS                            C_COBJ#                        BBB  
  15.   
  16. 10 rows selected.  
  17.   
  18.   
  19. Execution Plan  
  20. ----------------------------------------------------------  
  21. Plan hash value: 4050478946  
  22.   
  23. -----------------------------------------------------------------------------------------------  
  24. | Id  | Operation                   | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |  
  25. -----------------------------------------------------------------------------------------------  
  26. |   0 | SELECT STATEMENT            |         |    10 |   560 |       |   308   (1)| 00:05:09 |  
  27. |   1 |  NESTED LOOPS               |         |    10 |   560 |       |   308   (1)| 00:05:09 |  
  28. |   2 |   VIEW                      |         |    10 |   120 |       |   298   (1)| 00:04:59 |  
  29. |   3 |    SORT ORDER BY            |         |    10 |   160 |  2248K|   298   (1)| 00:04:59 |  
  30. |*  4 |     COUNT STOPKEY           |         |       |       |       |            |          |  
  31. |   5 |      TABLE ACCESS FULL      | T_TEST1 | 47585 |   743K|       |    45   (0)| 00:00:46 |  
  32. |   6 |   TABLE ACCESS BY USER ROWID| T_TEST1 |     1 |    44 |       |     1   (0)| 00:00:02 |  
  33. -----------------------------------------------------------------------------------------------  
  34.   
  35. Predicate Information (identified by operation id):  
  36. ---------------------------------------------------  
  37.   
  38.    4 - filter(ROWNUM<=10)  
  39.   
  40.   
  41. Statistics  
  42. ----------------------------------------------------------  
  43.           0  recursive calls  
  44.           0  db block gets  
  45.          14  consistent gets  
  46.           0  physical reads  
  47.           0  redo size  
  48.         707  bytes sent via SQL*Net to client  
  49.         385  bytes received via SQL*Net from client  
  50.           2  SQL*Net roundtrips to/from client  
  51.           1  sorts (memory)  
  52.           0  sorts (disk)  
  53.          10  rows processed  

However, according to the execution plan and result, it does not run as we expected, and the result is also wrong. The reason is that optimizer is not sure index containing all records because of un-indexed NULL values.

We get what we want as soon as we added the constraint.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify subobject_name not null;  
  2.   
  3. Table altered.  
  4.   
  5. HELLODBA.COM>select owner,object_name,subobject_name from t_test1 t1, (select /*+index(t t_test1_subo_idx)*/rowid rid from t_test1 t where rownum<=10  
  6. order by subobject_name) v where t1.rowid=v.rid;  
  7.   
  8. OWNER                          OBJECT_NAME                    SUBOBJECT_NAME  
  9. ------------------------------ ------------------------------ ------------------------------  
  10. DEMO                           NO                             A  
  11. DEMO                           NO                             A  
  12. DEMO                           NO                             A  
  13. SYS                            ICOL$                          BBB  
  14. SYS                            I_USER1                        BBB  
  15. SYS                            CON$                           BBB  
  16. SYS                            UNDO$                          BBB  
  17. SYS                            C_COBJ#                        BBB  
  18. SYS                            I_OBJ#                         BBB  
  19. SYS                            PROXY_ROLE_DATA$               BBB  
  20.   
  21. 10 rows selected.  
  22.   
  23.   
  24. Execution Plan  
  25. ----------------------------------------------------------  
  26. Plan hash value: 3198566056  
  27.   
  28. ------------------------------------------------------------------------------------------------  
  29. | Id  | Operation                   | Name             | Rows  | Bytes | Cost (%CPU)| Time     |  
  30. ------------------------------------------------------------------------------------------------  
  31. |   0 | SELECT STATEMENT            |                  |    10 |   560 |    71   (0)| 00:01:11 |  
  32. |   1 |  NESTED LOOPS               |                  |    10 |   560 |    71   (0)| 00:01:11 |  
  33. |   2 |   VIEW                      |                  |    10 |   120 |    61   (0)| 00:01:01 |  
  34. |*  3 |    COUNT STOPKEY            |                  |       |       |            |          |  
  35. |   4 |     INDEX FULL SCAN         | T_TEST1_SUBO_IDX | 47585 |   743K|    61   (0)| 00:01:01 |  
  36. |   5 |   TABLE ACCESS BY USER ROWID| T_TEST1          |     1 |    44 |     1   (0)| 00:00:02 |  
  37. ------------------------------------------------------------------------------------------------  
  38.   
  39. Predicate Information (identified by operation id):  
  40. ---------------------------------------------------  
  41.   
  42.    3 - filter(ROWNUM<=10)  
  43.   
  44.   
  45. Statistics  
  46. ----------------------------------------------------------  
  47.           0  recursive calls  
  48.           0  db block gets  
  49.          13  consistent gets  
  50.           0  physical reads  
  51.           0  redo size  
  52.         681  bytes sent via SQL*Net to client  
  53.         385  bytes received via SQL*Net from client  
  54.           2  SQL*Net roundtrips to/from client  
  55.           0  sorts (memory)  
  56.           0  sorts (disk)  
  57.          10  rows processed  

NOT NULL constraint impact on JOIN

NOT NULL constraint also impacts on optimizer choosing JOIN methods in excution plan. Let's create anthoer table.

SQL代码
  1. HELLODBA.COM>create table t_test2 tablespace DEMO as select * from dba_tables;  
  2.   
  3. Table created.  
  4.   
  5. HELLODBA.COM>alter table T_TEST2 add constraint T_TEST2_PK primary key (OWNER,TABLE_NAME) using index  tablespace DEMOTSINX;  
  6.   
  7. Table altered.  
  8.   
  9. HELLODBA.COM>desc t_test2  
  10.  Name          Null?    Type  
  11. -------------- -------- -----------------  
  12.  OWNER         NOT NULL VARCHAR2(30)  
  13.  TABLE_NAME    NOT NULL VARCHAR2(30)  
  14.  TABLESPACE_NAME        VARCHAR2(30)  
  15.  CLUSTER_NAME           VARCHAR2(30)  
  16.  IOT_NAME               VARCHAR2(30)  
  17.  STATUS                 VARCHAR2(8)  
  18.  PCT_FREE               NUMBER  
  19.  PCT_USED               NUMBER  
  20. ...  

Remove the NOT NULL constraint again.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify subobject_name null;  
  2.   
  3. Table altered.  

We execute below query to find records in T_TEST1 with subobject_name is not table_name.

SQL代码
  1. HELLODBA.COM>select t1.owner, t1.object_name, t1.subobject_name from t_test1 t1 where subobject_name not in (select table_name from t_test2 t2);  
  2.   
  3. 45135 rows selected.  
  4.   
  5.   
  6. Execution Plan  
  7. ----------------------------------------------------------  
  8. Plan hash value: 3538907136  
  9.   
  10. ------------------------------------------------------------------------------  
  11. | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |  
  12. ------------------------------------------------------------------------------  
  13. |   0 | SELECT STATEMENT   |         |  2379 | 76128 |    51   (0)| 00:00:52 |  
  14. |*  1 |  FILTER            |         |       |       |            |          |  
  15. |   2 |   TABLE ACCESS FULL| T_TEST1 | 47585 |  1487K|    45   (0)| 00:00:46 |  
  16. |*  3 |   TABLE ACCESS FULL| T_TEST2 |     1 |    18 |     6   (0)| 00:00:07 |  
  17. ------------------------------------------------------------------------------  
  18.   
  19. Predicate Information (identified by operation id):  
  20. ---------------------------------------------------  
  21.   
  22.    1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "T_TEST2" "T2" WHERE  
  23.               LNNVL("TABLE_NAME"<>:B1)))  
  24.    3 - filter(LNNVL("TABLE_NAME"<>:B1))  
  25.   
  26.   
  27. Statistics  
  28. ----------------------------------------------------------  
  29.         392  recursive calls  
  30.           0  db block gets  
  31.     2217674  consistent gets  
  32.           0  physical reads  
  33.           0  redo size  
  34.     2329590  bytes sent via SQL*Net to client  
  35.       33473  bytes received via SQL*Net from client  
  36.        3010  SQL*Net roundtrips to/from client  
  37.           5  sorts (memory)  
  38.           0  sorts (disk)  
  39.       45135  rows processed  

We notcie that execution plan invovled with function LNNVL, NOT EXISTS as well as FILTER to get the result, with poor performance.

Note: The LNNVL function provides a concise way to evaluate a condition when one or both operands of the condition may be null.

And we add the NOT NULL constraint again.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify subobject_name not null;  
  2.   
  3. Table altered.  
  4.   
  5. HELLODBA.COM>select /*+ordered*/t1.owner, t1.object_name, t1.subobject_name from t_test1 t1 where not exists (select 1 from t_test2 t2 where t1.subobject_name = t2.table_name);  
  6.   
  7. 45135 rows selected.  
  8.   
  9.   
  10. Execution Plan  
  11. ----------------------------------------------------------  
  12. Plan hash value: 3049160152  
  13.   
  14. ---------------------------------------------------------------------------------------  
  15. | Id  | Operation           | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |  
  16. ---------------------------------------------------------------------------------------  
  17. |   0 | SELECT STATEMENT    |         |     1 |    50 |       |   475   (1)| 00:07:56 |  
  18. |   1 |  MERGE JOIN ANTI    |         |     1 |    50 |       |   475   (1)| 00:07:56 |  
  19. |   2 |   SORT JOIN         |         | 47585 |  1487K|  4136K|   458   (1)| 00:07:39 |  
  20. |   3 |    TABLE ACCESS FULL| T_TEST1 | 47585 |  1487K|       |    45   (0)| 00:00:46 |  
  21. |*  4 |   SORT UNIQUE       |         |  2070 | 37260 |   120K|    17   (6)| 00:00:18 |  
  22. |   5 |    TABLE ACCESS FULL| T_TEST2 |  2070 | 37260 |       |     6   (0)| 00:00:07 |  
  23. ---------------------------------------------------------------------------------------  
  24.   
  25. Predicate Information (identified by operation id):  
  26. ---------------------------------------------------  
  27.   
  28.    4 - access("T1"."SUBOBJECT_NAME"="T2"."TABLE_NAME")  
  29.        filter("T1"."SUBOBJECT_NAME"="T2"."TABLE_NAME")  
  30.   
  31.   
  32. Statistics  
  33. ----------------------------------------------------------  
  34.          41  recursive calls  
  35.         141  db block gets  
  36.         882  consistent gets  
  37.        1432  physical reads  
  38.           0  redo size  
  39.     2050667  bytes sent via SQL*Net to client  
  40.       33473  bytes received via SQL*Net from client  
  41.        3010  SQL*Net roundtrips to/from client  
  42.           0  sorts (memory)  
  43.           2  sorts (disk)  
  44.       45135  rows processed  

The execution plan adopts ANTI-JOIN to get data, with better performance.

As we know, we should use IS NULL or IS NOT NULL to identify NULL values, otherwise, the expression will always reture FALSE if it involved NULL. That's why NULL VALUES do not impact JOIN or SEMI-JOIN.

SQL代码
  1. HELLODBA.COM>select 1 from dual where null='';  
  2.   
  3. no rows selected  
  4.   
  5. HELLODBA.COM>select 1 from dual where null=null;  
  6.   
  7. no rows selected  
  8.   
  9. HELLODBA.COM>select 1 from dual where null is null;  
  10.   
  11.          1  
  12. ----------  
  13.          1  

ANTI-JOIN identifies data with JOIN methods (NESTED-LOOP, MERGE, HASH). Once it finds records matched with JOIN criteria, it spots the record should be discarded and will not match remaining data in a data set, which quite improved performance. When join data, it involves equal (=) matcher, which is not suitable for NULL data, therefore, optimizer will not adopt ANTI-JOIN if there is potential NULL values in the join columns.

Note: with NULL values or not, NOT EXISTS clause could adopt ANTI-JOIN, but its logic is not same as NOT IN. The results are different in below case.

SQL代码
  1. HELLODBA.COM>alter table t_test1 modify subobject_name null;  
  2.   
  3. Table altered.  
  4.   
  5. HELLODBA.COM>update t_test1 set subobject_name=null where rownum <=10;  
  6.   
  7. 10 rows updated.  
  8.   
  9. HELLODBA.COM>select t1.owner, t1.object_name, t1.subobject_name from t_test1 t1 where subobject_name not in (select table_name from t_test2 t2);  
  10.   
  11. 45129 rows selected.  
  12.   
  13. Execution Plan  
  14. ----------------------------------------------------------  
  15. Plan hash value: 3538907136  
  16.   
  17. ------------------------------------------------------------------------------  
  18. | Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |  
  19. ------------------------------------------------------------------------------  
  20. |   0 | SELECT STATEMENT   |         |  2379 | 76128 |    51   (0)| 00:00:52 |  
  21. |*  1 |  FILTER            |         |       |       |            |          |  
  22. |   2 |   TABLE ACCESS FULL| T_TEST1 | 47585 |  1487K|    45   (0)| 00:00:46 |  
  23. |*  3 |   TABLE ACCESS FULL| T_TEST2 |     1 |    18 |     6   (0)| 00:00:07 |  
  24. ------------------------------------------------------------------------------  
  25.   
  26. Predicate Information (identified by operation id):  
  27. ---------------------------------------------------  
  28.   
  29.    1 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "T_TEST2" "T2" WHERE  
  30.               LNNVL("TABLE_NAME"<>:B1)))  
  31.    3 - filter(LNNVL("TABLE_NAME"<>:B1))  
  32.   
  33.   
  34. Statistics  
  35. ----------------------------------------------------------  
  36.         745  recursive calls  
  37.         216  db block gets  
  38.     2217413  consistent gets  
  39.          13  physical reads  
  40.           0  redo size  
  41.     2329442  bytes sent via SQL*Net to client  
  42.       33473  bytes received via SQL*Net from client  
  43.        3010  SQL*Net roundtrips to/from client  
  44.          26  sorts (memory)  
  45.           0  sorts (disk)  
  46.       45129  rows processed  
  47.   
  48. HELLODBA.COM>select t1.owner, t1.object_name, t1.subobject_name from t_test1 t1 where not exists (select 1 from t_test2 t2 where t1.subobject_name = t  
  49. 2.table_name);  
  50.   
  51. 45139 rows selected.  
  52.   
  53. Execution Plan  
  54. ----------------------------------------------------------  
  55. Plan hash value: 2383621862  
  56.   
  57. --------------------------------------------------------------------------------  
  58. | Id  | Operation            | Name    | Rows  | Bytes | Cost (%CPU)| Time     |  
  59. --------------------------------------------------------------------------------  
  60. |   0 | SELECT STATEMENT     |         |     1 |    50 |    52   (2)| 00:00:52 |  
  61. |*  1 |  HASH JOIN RIGHT ANTI|         |     1 |    50 |    52   (2)| 00:00:52 |  
  62. |   2 |   TABLE ACCESS FULL  | T_TEST2 |  2070 | 37260 |     6   (0)| 00:00:07 |  
  63. |   3 |   TABLE ACCESS FULL  | T_TEST1 | 47585 |  1487K|    45   (0)| 00:00:46 |  
  64. --------------------------------------------------------------------------------  
  65.   
  66. Predicate Information (identified by operation id):  
  67. ---------------------------------------------------  
  68.   
  69.    1 - access("T1"."SUBOBJECT_NAME"="T2"."TABLE_NAME")  
  70.   
  71.   
  72. Statistics  
  73. ----------------------------------------------------------  
  74.          49  recursive calls  
  75.         360  db block gets  
  76.        4130  consistent gets  
  77.           0  physical reads  
  78.           0  redo size  
  79.     2329713  bytes sent via SQL*Net to client  
  80.       33484  bytes received via SQL*Net from client  
  81.        3011  SQL*Net roundtrips to/from client  
  82.           2  sorts (memory)  
  83.           0  sorts (disk)  
  84.       45139  rows processed  
  85.   
  86. HELLODBA.COM>rollback;  
  87.   
  88. Rollback complete.  

--- Fuyuncat ---

Top

Copyright ©2005, HelloDBA.Com All reseverd.

Declaration
by fuyuncat