Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Oracle Foreign Key Retrieval SQL Statement #1333

Closed
tibramo opened this issue Nov 15, 2023 · 5 comments
Closed

Optimize Oracle Foreign Key Retrieval SQL Statement #1333

tibramo opened this issue Nov 15, 2023 · 5 comments
Assignees

Comments

@tibramo
Copy link

tibramo commented Nov 15, 2023

Feature Request

Problem Description

The current SQL statement for retrieving all foreign keys in Oracle, as provided in FOREIGN_KEYS.sql, may lead to performance issues and errors in certain scenarios. For instance, in our database, the current implementation resulted in an "ORA-01652: unable to extend temp segment" error after more than 40 minutes of execution time.

Proposed Solution

I propose optimizing the existing SQL statement using explicit JOIN statements. Below is a modified version of the SQL statement that significantly improves performance, reducing the execution time to 4 seconds in our testing environment:

SELECT
    NULL AS PKTABLE_CAT,
    P.OWNER AS PKTABLE_SCHEM,
    P.TABLE_NAME AS PKTABLE_NAME,
    PC.COLUMN_NAME AS PKCOLUMN_NAME,
    NULL AS FKTABLE_CAT,
    F.OWNER AS FKTABLE_SCHEM,
    F.TABLE_NAME AS FKTABLE_NAME,
    FC.COLUMN_NAME AS FKCOLUMN_NAME,
    FC.POSITION AS KEY_SEQ,
    NULL AS UPDATE_RULE,
    DECODE(F.DELETE_RULE, 'CASCADE', 0, 'SET NULL', 2, 1) AS DELETE_RULE,
    F.CONSTRAINT_NAME AS FK_NAME,
    P.CONSTRAINT_NAME AS PK_NAME,
    DECODE(F.DEFERRABLE, 'DEFERRABLE', 5, 'NOT DEFERRABLE', 7, 'DEFERRED', 6) AS DEFERRABILITY
FROM
    ALL_CONSTRAINTS P
        JOIN
    ALL_USERS USERS ON P.OWNER = USERS.USERNAME
        JOIN
    ALL_CONSTRAINTS F ON P.OWNER = F.R_OWNER AND F.CONSTRAINT_TYPE = 'R' AND P.CONSTRAINT_NAME = F.R_CONSTRAINT_NAME
        JOIN
    ALL_CONS_COLUMNS PC ON PC.OWNER = P.OWNER AND PC.CONSTRAINT_NAME = P.CONSTRAINT_NAME AND PC.TABLE_NAME = P.TABLE_NAME
        JOIN
    ALL_CONS_COLUMNS FC ON FC.OWNER = F.OWNER AND FC.CONSTRAINT_NAME = F.CONSTRAINT_NAME AND FC.TABLE_NAME = F.TABLE_NAME AND FC.POSITION = PC.POSITION
WHERE
  1 = 1
  AND USERS.ORACLE_MAINTAINED = 'N'
  AND NOT REGEXP_LIKE(USERS.USERNAME, '^APEX_[0-9]{6}$')
  AND NOT REGEXP_LIKE(USERS.USERNAME, '^FLOWS_[0-9]{5}$')
  AND REGEXP_LIKE(P.OWNER, 'DM_CORE999')
  AND P.CONSTRAINT_TYPE IN ('P', 'U')
ORDER BY
    PKTABLE_SCHEM,
    PKTABLE_NAME,
    KEY_SEQ;

Possible Alternatives

No response

Additional Context

No response

@sualeh
Copy link
Collaborator

sualeh commented Nov 16, 2023

@timo-brandes Thanks for reporting this, and testing the improved query. I have fixed the code in SchemaCrawler, and will release it with the next release.

@tibramo
Copy link
Author

tibramo commented Nov 16, 2023

@sualeh Thank you for updating the query and your hard work on this project.

@sualeh
Copy link
Collaborator

sualeh commented Nov 17, 2023

@timo-brandes Please use SchemaCrawler v16.20.6, and let me know if it helps.

@tibramo
Copy link
Author

tibramo commented Nov 20, 2023

@sualeh Thanks for the release, it is working – and fast :)

@sualeh
Copy link
Collaborator

sualeh commented Nov 20, 2023

@timo-brandes Thanks for the confirmation, and thanks for your query!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants