我并不是说这个是“它”,但......可能是。
可能是什么原因
看起来像未索引的外键问题。基本上,所有外键列都应该被索引。正如documentation 所说:
为子表中的外键建立索引有以下好处:
- 防止子表上的全表锁定。相反,数据库会在索引上获取行锁。
欲了解更多信息,请阅读Locks and foreign keys。
我该如何解决?
显然,通过索引外键列。但是,首先你必须找到它们。我使用的是 Tom Kyte 的脚本(稍作调整):
/* 12.12.2012. Tom Kyte: locating unindexed foreign keys
14.03.2016. PAR_WHAT: 0 - show those that aren't OK
1 - show those that are OK
NULL - show all
*/
WITH forkey
AS (SELECT DECODE (b.table_name, NULL, '****', 'ok') Status,
a.table_name,
a.columns column_1,
b.columns column_2
FROM ( SELECT SUBSTR (a.table_name, 1, 30) table_name,
SUBSTR (a.constraint_name, 1, 30) constraint_name,
MAX (
DECODE (position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_cons_columns a, user_constraints b
WHERE a.constraint_name = b.constraint_name
AND b.constraint_type = 'R'
GROUP BY SUBSTR (a.table_name, 1, 30),
SUBSTR (a.constraint_name, 1, 30)) a,
( SELECT SUBSTR (table_name, 1, 30) table_name,
SUBSTR (index_name, 1, 30) index_name,
MAX (
DECODE (column_position,
1, SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
2, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
3, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
4, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
5, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
6, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
7, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
8, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (column_position,
9, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
10, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
11, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
12, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
13, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
14, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
15, ', ' || SUBSTR (column_name, 1, 30),
NULL))
|| MAX (
DECODE (
column_position,
16, ', ' || SUBSTR (column_name, 1, 30),
NULL))
columns
FROM user_ind_columns
GROUP BY SUBSTR (table_name, 1, 30),
SUBSTR (index_name, 1, 30)) b
WHERE a.table_name = b.table_name(+)
AND b.columns(+) LIKE a.columns || '%'
AND a.table_name NOT LIKE 'HEP_DP%')
SELECT f.status,
f.table_name,
f.column_1,
f.column_2
FROM forkey f
WHERE f.status =
CASE
WHEN :par_what = 1 THEN 'ok'
WHEN :par_what = 0 THEN '****'
ELSE f.status
END
ORDER BY f.table_name, f.column_1, f.column_2
/
例如:
SQL> create table a (id number primary key);
Table created.
SQL> create table b (id number constraint fk_ba references a (id));
Table created.
表B 缺少其外键约束列上的索引,因此查询返回:
SQL> /
STATUS TABLE_NAME COLUMN_1 COLUMN_2
---------- ---------- ---------- ----------
**** B ID
创建索引:
SQL> create index a1bid on b (id);
Index created.
查询现在不返回任何内容:
SQL> /
no rows selected
看看有没有帮助。