Var det mig, ville jeg prøve at gribe problemet an på en anden måde. I stedet for at skrive en SQL-parser (hvilket ville kræve meget mere end et regulært udtryk, medmindre du kan garantere, at alle SQL-sætningerne bruger en meget lille delmængde af den tilgængelige SQL-grammatik), ville jeg have en tendens til at generere en forespørgselsplan for hvert objekt og derefter forespørgsel PLAN_TABLE
for at se de objekter, som Oracle skal ramme. Du skal foretage et ekstra opslag for indeksadgange for at finde ud af, hvilken tabel indekset er defineret på, men det burde være rimeligt ligetil.
Hvis du går ned ad denne vej, vil du dog hente de basistabeller, som din forespørgsel faktisk berører, snarere end de synspunkter, forespørgslerne rent faktisk refererer til. Det vil sige, hvis du har en forespørgsel SELECT * FROM view_1
og view_1
, er til gengæld defineret som en forespørgsel mod tabel_a
og tabel_b
, kun tabel_a
og tabel_b
vil være en del af planen. Og du bliver nødt til at deaktivere query_rewrite
for sessionen, hvis du ville forhindre forespørgselsplanerne i at referere til materialiserede visninger, hvis disse materialiserede visninger ikke specifikt var en del af forespørgslen.
Hvis du for hver forespørgsel laver en
FORKLÆR PLAN FOR <>
du kan derefter
SELECT DISTINCT object_owner, object_name, object_type FROM plant_table
for at få listen over objekter. Hvis OBJECT_TYPE
er som INDEX%
, kan du derefter bruge DBA_INDEXES
visning (eller ALL_INDEXES
eller USER_INDEXES
afhængigt af, hvem der ejer de pågældende objekter, og hvilket niveau af privilegier du har) for at bestemme, hvilken tabel det indeks er defineret på
VÆLG tabelejer, tabelnavn FRA dba_indekser HVOR ejer =<> OG indeksnavn =<>
Så hvis jeg for eksempel har en visning view_1
opret eller erstat visning view_1 som vælg * fra emp join dept ved hjælp af (deptno)
og en forespørgsel
vælg * fra view_1;
Jeg kan gøre
SQL> forklar plan for vælg * fra view_1;Explained.SQL> edWrote-fil afiedt.buf 1 SELECT distinct object_owner, object_name, object_type 2* FROM plan_tableSQL> /OBJECT_OWNER OBJECT_NAME OBJECT_TYPE-------- ---------------------- -------------------------- --- ----------------------SCOTT DEPT TABLESCOTT PK_DEPT INDEX (UNIQUE)SCOTT EMP TABLE
Dette fortæller mig, at forespørgslen faktisk rammer EMP
og DEPT
borde. Den rammer også PK_DEPT
indeks, så jeg kan se, hvilken tabel der er defineret på.
SQL> edWrote-fil afiedt.buf 1 SELECT table_owner, table_name 2 FROM dba_indexes 3 WHERE ejer ='SCOTT' 4* OG index_name ='PK_DEPT'SQL> /TABLE_OWNER TABLE_NAME--------- -------------------- ------------------------------------ -SCOTT DEPT
Som det viser sig, er det indeks defineret på DEPT
tabellen også, så jeg ved, at kun EMP
og DEPT
tabeller i SCOTT
skema vil blive involveret i forespørgslen.