1. 程式人生 > >慎用create table as select,一定要注意預設值的問題---大一臨時表方法

慎用create table as select,一定要注意預設值的問題---大一臨時表方法

SQL > create table emp_copy as select * from emp where deptno=10;

第一,注意emp_copy表中沒有定義任何列名,因為我們在列子句中用萬用字元從emp表取得資料,讓Oracle像emp表中一樣生成emp_copy表中的列——相同名稱,相同資料型別定義。

第二,SQL*PLUS中可以發出的任何select語句可以放在create table as select 語句中,然後Oracle會自動獲得從emp表選擇的資料,在進emp_copy表中。但是 如果select語句的列子句中包括特定列清單,則create table子句要列出表中要包括的列,放在括號中,例如:

SQL > create table emp_copy_2 (empno,sal) as select empno, sal from emp where deptno=10;

========================================================

分類: Linux

大家都知道create table a as select * from b可以建立一個與b表結構一樣的表,但是在實際應用中最好不要這麼建立表。原因是這樣只建立表的結構,而不會將原表的預設值一起建立。

說白了,表結構出來了,預設值沒有。

另外,但是有一個我對一個大表執行create table a as select * from b

時候報了一個temp表空間不足,不知道是什麼原因,記錄一下。下次發現在處理吧。

----------------------------------------

一、Symptoms
        During CTAS (CREATE TABLE AS SELECT), be reported:
       ORA-01652: unable to extend temp segment by 1024 in tablespace <DATA>

二、Cause
        The tablespace where the object is being created doesnt have sufficient space to extend for the CTAS command to succeed.

三、Solution
        Modify the datafile associated for the tablespace to AUTOEXTEND ON till the CTAS command gets executed successfully.
       During the CTAS , it creates a data segment in the target tablespace and marks this segment as temporary in dictionary.
       Once the table created successfully , the dictionary type is changed from TEMPRORAY to TABLE. In addition, if the SELECT performs a SORT operation,temporary space may be used as for the same.

四、TEST CASE
       1. 建立表空間
          SQL> CREATE TABLESPACE TEST DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL10G\TEST.DBF' SIZE 10M AUTOEXTEND OFF;
           Tablespace created
        2. 為客戶分配預設表空間
          SQL> ALTER USER TESTER DEFAULT TABLESPACE TEST;
           User altered.
        3. 查詢物件實際大小
         SQL>SELECT BYTES/1024/1024,TABLESPACE_NAME FROM DBA_SEGMENTS WHERE SEGMENT_NAME='DUMMY';
                     11       system    --Size of the DUMMY object is 11 M
       4. CTAS建立新物件
          SQL> CONN TESTER/TESTER
                      Connected.
           SQL> CREATE TABLE DUMMY_123 AS SELECT * FROM SCOTT.DUMMY;
           CREATE TABLE DUMMY_123 AS SELECT * FROM SCOTT.DUMMY
           *
           ERROR at line 1:
           ORA-01652: unable to extend temp segment by 128 in tablespace TEST
      The above error message reported above is because the Tablespace TEST is of 10 M size and AUTOEXTEND OFF. The object about to be created "DUMMY_123 " , requires 11 M size and as it doesn't have enough space to extend , it has failed with the ORA-1652 error message in "TEST" tablespace.

一、Temporary Segments Concept
        Oracle often requires temporary work space for intermediate stages of database processing. There are different kinds of temporary segments in the database.
        Some of them are created explicitly by the users. The others are created and accessed for the user by the system.
       There are SQL operations containing a sorting step which require temporary segments. However, segments used for sorting are not the only segments having SEGMENT_TYPE=TEMPORARY. Temporary segments can also exist for permanent segments creation.

      Temporary segments for sorting are created in the default temporary tablespace of the user. This tablespace may be of type TEMPORARY or PERMANENT.
      (1)  A TEMPORARY tablespace (Locally Managed Tablespace) is recommended for sort operations.
      (2)  Temporary segments for permanent segments creation are created in the tablespace specified in the create statement or in the user’s default tablespace.

a.  Temporary Tables
     only exists during a transaction or session.
     DML statements on temporary tables do not generate redo logs for the data changes. However, undo logs for the data and redo logs for the undo logs are generated.
   
b.  Temporary LOBs
     The goal of temporary LOBs is to develop an interface to support the creation and deletion of lobs that act like local variables.
   
c.  Temporary Segments as work area for sorting
     When processing queries, Oracle often requires temporary workspace for intermediate stages of SQL statement execution.
     The sort area is allocated in memory. If the sort operation needs additional memory (above the value specified by the SORT_AREA_SIZE parameter), the sorted rows are written to disk to free up the sort area so that it can be re-used for the remaining sort.
    Oracle automatically allocates this disk space called a temporary segment.
    The following statements may require the use of a temporary segment for sorting:
   CREATE INDEX/SELECT ... ORDER BY/SELECT DISTINCT/SELECT ... GROUP BY/SELECT ... UNION/SELECT ... INTERSECT/SELECT ... MINUS/ANALYZE TABLE/Unindexed joins/Correlated subqueries

d.  Temporary Segments for permanent segments creation
     Besides sort operations, there are other SQL operations, which also require temporary segments:
   CREATE PRIMARY/UNIQUE KEY CONSTRAINT
    ALTER TABLE ... ENABLE PRIMARY/UNIQUE CONSTRAINT
    CREATE TABLE STORAGE (MINEXTENTS>1)
    CREATE TABLE AS SELECT
           The CTAS creates a data segment in the target tablespace and marks this segment as temporary in dictionary.
           On completion, the dictionary type is changed from temporary to table. In addition, if the SELECT performs a SORT operation, temporary space may be used as for a standard select.
   CREATE PARTITION TABLE
    ALTER TABLE ... SPLIT PARTITION
    CREATE SNAPSHOT
    CREATE INDEX
           The CREATE INDEX statement, after sorting the index values, builds a temporary segment in the INDEX tablespace;
           once the index is completely built, the segment type is changed to INDEX.
    DROP TABLE  
   
e.  Temporary Tablespaces

二、Introduction to Direct-Path INSERT
        1. Conventional insert operations:
            Oracle reuses free space in the table, interleaving newly inserted data with existing data. During such operations, Oracle also maintains referential integrity constraints.

        2. Direct-path INSERT operations:
           Oracle appends the inserted data after existing data in the table. Data is written directly into datafiles, bypassing the buffer cache. Free space in the existing data is not reused, and referential integrity constraints are ignored. These procedures combined can enhance performance.
            a. During direct-path INSERT, you can disable the logging of redo and undo entries
            b.CREATE TABLE ... AS SELECT statement, does not have any indexes defined on it and not null constraint; you must define them later.
  
Note:If the database or tablespace is in FORCE LOGGING mode, then direct path INSERT always logs, regardless of the logging or nologging setting, such as STANDBY database.



========================================================

Create table as select效能簡介:

在資料庫中移動資料最快的方法是將其從一個表移動到別一個表,而不是需要進入作業系統將資料從一個表移動到別一個表,有一些常見的方法可用於提高資料遷移的效能:

1.調整表的結構(刪除索引和觸發器)

2.在資料遷移期間禁用約束

3.使用提示和選項來改進事務效能

第一個技巧是調整表的結構,它涉及禁用目標表上面的任何觸發器或索引。例如,如果在目標表上有行級觸發器,則插入到表中的每一行都會執行觸發器。如果可能的話,最好在資料插入之前將目標表的觸發器禁用;如果應該為每個插入的行執行該觸發器,則可以在批量插入完成以後再建立此觸發器,而不應該在批量插入期間每插入一條資料重複執行觸發器。

除了禁用觸發器,應該在啟動資料載入之前刪除目標表上面的索引,然後在資料載入完畢後再重新建立索引。如果索引留在表上,ORACLE將在插入每一行時動態管理索引。

注意:刪除索引和禁用觸發器可以解決大多數數和大型表與表之間資料遷移中遇到的效能問題。

除了禁用索引,還要考慮到表上的約束。如果源資料已經在資料庫的表中,在將資料載入到目標表之前,可以檢查該資料瞭解它的相關約束(例如外來鍵或check約束),一旦載入資料完成就可以重新啟用這些約束。

如果以上選項無法提供適當的效能,就應該調查Oracle為資料遷移調整引入的選項。這些選項包括如下:

1.插入命令的APPPEND提示類似於Direct Path Loader,APPENED提示將資料塊載入到表中,從表的高水位線開始。使用APPENED提示可以增加空間利用率。

2Nologging選項如果正在執行create table as select 命令,使用nologing選項可避免在操作期間寫入重做日誌檔案。

3.並行選項並行查詢使用多個程序來完成一個任務。對於create table as select命令,可並行化create table 部分和查詢部分。如果使用並行選項,則也應該使用nologing選項,否則並行操作將不得不由於序列化寫入到聯機重做日誌檔案而等待。

在使用這些高階選項之前,應該首先調查目標表的結構,確保已經避免前面提到的一些常見問題。

分享到: 閱讀(2376)| 評論(0)| 轉載 (0) |舉報

========================================================

今天鄙人有意翻出ORACLE 9I Performance Tuning  的官方教材,看到原文:
  Using the CREATE TABLE ... AS SELECT ... command: This command will copy acrooss to the new table all the data,but the constraints triggers ,and so on will not be transferred to the new table.

  但本人在自己的生產庫的操作過程中,發現,只要是用as select CREATE的表,都是帶有原表的CONSTRINTS....

有誰能解釋一下,.

這難道是官方檔案的手誤???

Connected to Oracle9i Enterprise Edition Release 9.2.0.4.0 
Connected as serp01

SQL> select constraint_name from dba_constraints where table_name ='CRM_CUSTOMER';

CONSTRAINT_NAME
------------------------------
REFCRM_CUSTOMER2167
REFINV_WAREHOUSE482
REFINV_WAREHOUSE608
REFORG_EMPLOYEES0001
REFORG_EMPLOYEES1474
REFORG_ENTERPRISES1400
REFORG_ORGANIZATIONS000001
REFORG_ORGANIZATIONS2401
REFPUB_AREA_CODE379
REFPUB_CLASSIFY_CODE380
REFPUB_ENTERPRISE_TYPE_CODE381
REFPUB_INDUSTRY_CODE382
REFPUB_PAYCONDI_CODE0000001
REFTPUB_PAYMENT_CODE01
SYS_C0092306
SYS_C0092764
SYS_C0079060
SYS_C0079061
SYS_C0079062
SYS_C0079063

CONSTRAINT_NAME
------------------------------
SYS_C0079064
SYS_C0079065
SYS_C0079066
SYS_C0079067
SYS_C0079068
SYS_C0079069
SYS_C0079070
SYS_C0079071
SYS_C0079072
SYS_C0079073
SYS_C0079074
SYS_C0079075
SYS_C0079076
SYS_C0079077
SYS_C0079078
SYS_C0079079
SYS_C0079080
SYS_C0079081
SYS_C0079082
SYS_C0079083
SYS_C0079084

CONSTRAINT_NAME
------------------------------
SYS_C0079085
SYS_C0079086
SYS_C0079087
SYS_C0079088
SYS_C0079089
SYS_C0079090
SYS_C0079091
SYS_C0079092
SYS_C0079093
SYS_C0079094
SYS_C0079095
SYS_C0079096
SYS_C0079097
SYS_C0079098
SYS_C0079099
SYS_C0079100
SYS_C0079101
SYS_C0079102
SYS_C0079103
SYS_C0079104
SYS_C0079105

CONSTRAINT_NAME
------------------------------
SYS_C0079106
SYS_C0079107
SYS_C0079108
SYS_C0079109
PK19

67 rows selected

SQL> create table temp_h1 as select * from crm_customer where rownum<10;

create table temp_h1 as select * from crm_customer where rownum<10

ORA-00955: 名稱已由現有物件使用

SQL> drop table temp_h1;

Table dropped

SQL> create table temp_h1 as select * from crm_customer where rownum<10;

Table created

SQL> select constraint_name from dba_constraints where table_name ='TEMP_H1';

CONSTRAINT_NAME
------------------------------
SYS_C0093440
SYS_C0093441
SYS_C0093442
SYS_C0093443
SYS_C0093444
SYS_C0093445
SYS_C0093446
SYS_C0093447
SYS_C0093448
SYS_C0093449
SYS_C0093450
SYS_C0093451
SYS_C0093452
SYS_C0093453
SYS_C0093454
SYS_C0093455
SYS_C0093456
SYS_C0093457
SYS_C0093458
SYS_C0093459

CONSTRAINT_NAME
------------------------------
SYS_C0093460
SYS_C0093461
SYS_C0093462
SYS_C0093463
SYS_C0093464
SYS_C0093465
SYS_C0093466
SYS_C0093467
SYS_C0093468
SYS_C0093469
SYS_C0093470
SYS_C0093471
SYS_C0093472
SYS_C0093473
SYS_C0093474
SYS_C0093475
SYS_C0093476
SYS_C0093477
SYS_C0093478
SYS_C0093479
SYS_C0093480

CONSTRAINT_NAME
------------------------------
SYS_C0093481
SYS_C0093482
SYS_C0093483
SYS_C0093484
SYS_C0093485
SYS_C0093486
SYS_C0093487
SYS_C0093488
SYS_C0093489
SYS_C0093490
SYS_C0093491

52 rows selected

SQL>

A答:也許你有好幾個TEMP_H1, 在不同的SCHEMA裡.  試試

select owner, table_name from dba_tables where table_name ='TEMP_H1';

就會一目瞭然

B答:這個是不可能的,用ctas從組表必然要對錶加相應的約束等。。。。

C答:那些都是not null約束,其他的約束和trigger是帶不過來了,嚴格說來not null也是約束的一種,只不過教材上把它排除在外了吧。