2015-08-31 77 views
0

我們的項目中有一個巨大的Oracle SQL查詢,它使用許多視圖和表格作爲源數據。如何查找大型複雜查詢使用的源錶行

當我運行它時,有什麼方法可以通過這個大查詢找到從每個源表中獲取的行列表嗎?

基本上我們要做的就是在源表中創建最小數量的行,以便最外面最大的查詢返回至少一條記錄。

我試圖單獨運行較小的查詢。但這是非常耗時和乏味的。所以我想知道是否有一個更聰明的方法來做到這一點。

+0

「使最外面的大查詢返回至少一個記錄」 ......你只是想尋找一個匹配行的存在? –

+0

檢查執行計劃。它應該給你至少一個提示在哪個表上選擇了多少行。 –

回答

0

您可以使用細粒度訪問控制。這裏是你將如何做到這一點:

第1步:創建一個表來保存的rowid的列表(即,你在這個練習中尋找結果)

CREATE TABLE matt_selected_rowids (row_id rowid); 

第2步:創建一個FGAC處理程序,只要選擇了基表,就會添加謂詞。

CREATE OR REPLACE PACKAGE matt_fgac_handler IS 
    FUNCTION record_rowid (p_rowid rowid) RETURN NUMBER DETERMINISTIC; 
    FUNCTION add_rowid_predicate (d1 varchar2, d2 varchar2) RETURN VARCHAR2; 
END matt_fgac_handler; 


CREATE OR REPLACE PACKAGE BODY matt_fgac_handler IS 

    FUNCTION record_rowid (p_rowid rowid) RETURN NUMBER DETERMINISTIC IS 
    PRAGMA AUTONOMOUS_TRANSACTION; 
    BEGIN 
    INSERT INTO matt_selected_rowids(row_id) values (p_rowid); 
    COMMIT; 
    RETURN -1; 
    END record_rowid; 



    FUNCTION add_rowid_predicate (d1 varchar2, d2 varchar2) RETURN VARCHAR2 IS 
    BEGIN 
    RETURN 'matt_fgac_handler.record_rowid (rowid) = -1'; 
    END add_rowid_predicate; 
END matt_fgac_handler; 

第3步:添加策略由您的視圖中使用的每一個基表(您可以通過使用遞歸DBA_DEPENDENCIES,或者只是做一個解釋計劃並目測它獲取列表)。

例如,

CREATE TABLE matt_table (a number, b varchar2(80)); 
CREATE INDEX matt_table_n1 on matt_table(a); 

insert into matt_table values (1,'A'); 
insert into matt_table values (2,'B'); 
insert into matt_table values (3,'C'); 
insert into matt_table values (3,'D'); 
insert into matt_table values (3,'E'); 
insert into matt_table values (3,'F'); 
insert into matt_table values (4,'G'); 
insert into matt_table values (4,'H'); 
COMMIT; 
BEGIN 
    DBMS_RLS.ADD_POLICY('APPS','MATT_TABLE','record_rowids_policy', NULL, 'matt_fgac_handler.add_rowid_predicate', 'select'); 
END; 

所以,在這一點上,只要用戶從我的表中進行選擇,甲骨文會自動將添加調用我的每個ROWID record_rowid功能的條件。

例如:

delete from matt_selected_rowids; 
SELECT /*+ INDEX */ * FROM matt_table where a = 2; 
-- This gives your the rowids selected... 
select r.row_id, o.object_name from matt_selected_rowids r left join dba_objects o on o.object_id =dbms_rowid.rowid_object(row_id);