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)
);
CHILD.PARENT_ID
上没有索引,因此修改/删除 PARENT
的开销很大(Oracle 需要对 CHILD.PARENT_ID
进行全表扫描>CHILD 以强制引用完整性)。然而以下语句的执行计划...
DELETE FROM PARENT WHERE PARENT_ID = 1
...不显示表扫描(SYS_C0070229 是 PARENT.PARENT_ID
上的索引):
我知道有办法 查看所有未索引的外键,但如果我能够“警告”潜在问题,那就更好了查询执行计划本身(顺便说一句,MS SQL Server 和其他数据库可能会这样做)。
在 Oracle 中这可能吗?
如果重要的话,我正在使用 Oracle 10.2。
Consider the following (simplistic) situation:
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)
);
There is no index on CHILD.PARENT_ID
, so modifying/deleting PARENT
is expensive (Oracle needs to do a full table scan on CHILD
to enforce the referential integrity). Yet the execution plan for the following statement...
DELETE FROM PARENT WHERE PARENT_ID = 1
...does not show the table scan (SYS_C0070229 is the index on PARENT.PARENT_ID
):
I know there are ways to see all unindexed FOREIGN KEYs, but it would be even better if I could be "warned" of a potential problem in the query execution plan itself (BTW, MS SQL Server and possibly other databases do that).
Is that possible in Oracle?
I'm using Oracle 10.2 if that matters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已经更改了您的约束以添加“ON DELETE CASCADE”,否则 Oracle 将引发错误。(外键违规的默认设置是删除限制)
我相信您问题的答案是“否” ",Oracle 不会警告您有关未索引的外键列。实际上,大多数此类列都会建立索引,因为这是将父级连接到子级的方式。
如果您想向某人证明没有索引会导致锁定问题和升级(不太理想的情况),您可以简单地禁用表锁并显示错误。
对于解释计划问题,正如其他人指出的那样,从子表中删除的sql是递归SQL,并且没有在解释计划中显示。
如果您跟踪会话,您将看到递归 SQL。
有用的链接:http://www.oracle-base.com/articles/10g/ SQLTrace10046TrcsessAndTkprof10g.php
I have altered your constraint to add the "ON DELETE CASCADE", without which Oracle will raise an error.(The default for foreign key violations is delete restrict)
I believe the answer to your question is "NO", Oracle does not warn you about the unindexed foreign key column. In practice, most such columns are indexed, since this is how you would be joining the parent to the child.
If you want to prove to someone that not having an index will cause locking issues and escalations (something not very desirable), you could simply disable the table lock and show the error.
And for the explain plan question, as others have pointed out, the sql to delete from the child table is a recursive SQL and is not shown in the explain plan.
If you TRACE the session, you'll see the recursive SQL.
Useful Links : http://www.oracle-base.com/articles/10g/SQLTrace10046TrcsessAndTkprof10g.php
强制引用完整性的查询是“递归sql”(即由Oracle生成),因此不会出现在解释计划中。如果您实际执行操作并跟踪它,您也会看到递归 sql。
The query to enforce the referential integrity is "recursive sql" (i.e. generated by Oracle), therefore will not show up in the explain plan. If you actually perform the operation and trace it, you'll see the recursive sql as well.