如何查找大型复杂查询使用的源表行

时间:2015-08-31 20:55:55

标签: sql oracle

我们的项目中有一个巨大的Oracle SQL查询,它使用许多视图和表来获取源数据。

当我运行它时,有没有办法找到这个大查询从每个源表中提取的行列表?

基本上我们要做的是在源表中创建最小的行数,以便最外层的查询返回至少一条记录。

我试图单独运行较小的查询。但这真的很耗时且乏味。所以我想知道是否有更聪明的方法。

1 个答案:

答案 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_DEPENDENCI来获取列表,或者只是执行解释计划并进行眼球)。

如,

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;

所以,此时,只要用户从我的表中选择,Oracle就会自动添加一个为每个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);