2012-02-15 31 views
5

xem xét như sau (đơn giản) tình hình:Kế hoạch thực hiện khóa ngoài của Oracle?

CREATE TABLE PARENT (
    PARENT_ID INT PRIMARY KEY 
); 

CREATE TABLE CHILD (
    CHILD_ID INT PRIMARY KEY, 
    PARENT_ID INT NOT NULL, 
    FOREIGN KEY (PARENT_ID) REFERENCES PARENT (PARENT_ID) 
); 

Không có chỉ mục trên CHILD.PARENT_ID, vì vậy giúp chỉnh sửa/xóa PARENT là tốn kém (Oracle cần phải làm một bảng đầy đủ quét trên CHILD để thực thi toàn vẹn tham chiếu). Tuy nhiên, kế hoạch thực hiện cho các tuyên bố sau ...

DELETE FROM PARENT WHERE PARENT_ID = 1 

... không hiển thị bảng quét (SYS_C0070229 là chỉ số trên PARENT.PARENT_ID):

query plan

Tôi biết có nhiều cách đến see all unindexed FOREIGN KEYs, nhưng sẽ tốt hơn nếu tôi có thể bị "cảnh báo" về một vấn đề tiềm ẩn trong kế hoạch thực thi truy vấn (BTW, MS SQL Server và các cơ sở dữ liệu khác có thể làm điều đó).

Điều đó có thể thực hiện được trong Oracle không?

Tôi đang sử dụng Oracle 10.2 nếu vấn đề đó quan trọng.

+1

Tôi không chắc chắn nếu bạn có quyền truy cập vào này hay không, nhưng Oracle SQL Phân tích (http://docs.oracle.com/html/A86647_01/vmqintro.htm) có một số tính năng mạnh mẽ để phân tích và điều chỉnh SQL. –

+0

@ZackMacomber Cảm ơn, tôi không quen với nó nhưng tôi chắc chắn rằng tôi sẽ học. Nó sẽ thực sự làm những gì tôi hỏi? –

Trả lời

4

Tôi đã thay đổi hạn chế của mình để thêm "ON DELETE CASCADE", mà không có Oracle sẽ nâng cao một lỗi. (Giá trị mặc định cho vi phạm nước ngoài chính là xóa hạn chế)

Tôi tin rằng câu trả lời cho câu hỏi của bạn là "KHÔNG", Oracle không cảnh báo bạn về cột khóa ngoài không được lập chỉ mục. Trong thực tế, hầu hết các cột như vậy được lập chỉ mục, vì đây là cách bạn sẽ tham gia cha mẹ với đứa trẻ.

Nếu bạn muốn chứng minh cho người không có chỉ mục sẽ gây ra vấn đề về khóa và leo thang (điều gì đó không mong muốn), bạn có thể tắt khóa bảng và hiển thị lỗi.

SQL> alter table child disable table lock; 

Table altered. 

SQL> delete from parent where parent_id = 10; 
delete from parent where parent_id = 10 
      * 
ERROR at line 1: 
ORA-00069: cannot acquire lock -- table locks disabled for CHILD 

Và đối với câu hỏi kế hoạch giải thích, như những người khác đã chỉ ra, sql cần xóa khỏi bảng con là SQL đệ quy và không được hiển thị trong kế hoạch giải thích.

Nếu bạn TRACE phiên, bạn sẽ thấy SQL đệ quy.

1* alter session set SQL_TRACE = TRUE 
SQL>/

Session altered. 

SQL> delete from parent where parent_id = 10; 

1 row deleted. 

SQL> commit; 

Commit complete. 

SQL> alter session set SQL_TRACE=FALSe; 

Session altered. 

===================== 
PARSING IN CURSOR #2 len=39 dep=0 uid=65 oct=7 lid=65 tim=763167901560 hv=3048246147 ad='3160891c' 
delete from parent where parent_id = 10 
END OF STMT 
PARSE #2:c=0,e=61,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=763167901555 
===================== 
PARSING IN CURSOR #1 len=48 dep=1 uid=0 oct=7 lid=0 tim=763167976106 hv=2120075951 ad='26722c20' 
delete from "RC"."CHILD" where "PARENT_ID" = :1 
END OF STMT 
PARSE #1:c=0,e=42,p=0,cr=0,cu=0,mis=0,r=0,dep=1,og=4,tim=763167976100 
EXEC#1:c=0,e=291,p=0,cr=7,cu=7,mis=0,r=2,dep=1,og=4,tim=763168080347 
EXEC#2:c=0,e=130968,p=0,cr=8,cu=14,mis=0,r=1,dep=0,og=1,tim=763168091605 
STAT #2 id=1 cnt=1 pid=0 pos=1 obj=0 op='DELETE PARENT (cr=8 pr=0 pw=0 time=130887 us)' 
STAT #2 id=2 cnt=1 pid=1 pos=1 obj=58703 op='INDEX UNIQUE SCAN SYS_C006951 (cr=1 pr=0 pw=0 time=19 us)' 
STAT #1 id=1 cnt=0 pid=0 pos=1 obj=0 op='DELETE CHILD (cr=7 pr=0 pw=0 time=233 us)' 
STAT #1 id=2 cnt=2 pid=1 pos=1 obj=58704 op='TABLE ACCESS FULL CHILD (cr=7 pr=0 pw=0 time=76 us)' 

Liên kết hữu ích: http://www.oracle-base.com/articles/10g/SQLTrace10046TrcsessAndTkprof10g.php

2

Truy vấn để thực thi tính toàn vẹn tham chiếu là "sql đệ quy" (tức là do Oracle tạo), do đó sẽ không hiển thị trong kế hoạch giải thích. Nếu bạn thực sự thực hiện thao tác và theo dõi nó, bạn sẽ thấy sql đệ quy.

+0

'SET AUTOTRACE ON' vẫn hiển thị cùng một kế hoạch thực hiện. Có điều gì đặc biệt tôi nên làm để xem "đệ quy SQL" này? –

+0

@Branko - để xem SQL đệ quy, bạn cần phải chạy một dấu vết trên phiên. –

Các vấn đề liên quan