我有一个包含三个互斥列的表。
create table key_tab
(
a_key number null,
b_key number null,
c_key number null,
key_tab_key number not null <-- Primary Key
)
/
示例:当填充 A_KEY 时,B_KEY 和 C_KEY 都为空。
我有一个 SELECT 语句如下:
select CASE INP_KEY
WHEN 'A' THEN
select A_KEY from KEY_TAB where A_KEY=:2 AND KEY_TAB_KEY =:3
WHEN 'B' THEN
select B_KEY from KEY_TAB where B_KEY=:2 and KEY_TAB_KEY = :3
WHEN 'C' then
select C_KEY from KEY_TAB where C_KEY=:2 and KEY_TAB_KEY = :3
END FROM dual
我创建了一个基于函数的索引,如下所示:
unique index key_tab_ix on key_tab
( case when a_key is not null then a_key
when b_key is not null then b_key
when c_key is not null then c_key
end,
key_tab_key
我有一个进程读取临时表,然后查询 KEY_TAB。如果未找到记录,则会将该记录插入到 KEY_TAB 中。
对于前 100 条记录,该过程运行速度非常快,然后速度急剧减慢。这可能是因为最初有很多记录需要搜索,但随着表的增长 - 它有更多的记录需要搜索。而且该索引似乎没有帮助。
任何帮助将不胜感激。
最佳答案
如果保证 a_key、b_key 和 c_key 中只有一个不为空(例如使用检查约束),那么您可以将唯一索引创建为:
create unique index key_tab_ix on key_tab (coalesce(a_key,b_key,c_key));
我会将您的选择语句更改为以下内容:
select A_KEY from KEY_TAB where A_KEY=:2 AND KEY_TAB_KEY = :3 and INP_KEY = 'A'
union all
select B_KEY from KEY_TAB where B_KEY=:2 and KEY_TAB_KEY = :3 and INP_KEY = 'B'
union all
select C_KEY from KEY_TAB where C_KEY=:2 and KEY_TAB_KEY = :3 and INP_KEY = 'C'
或者您甚至可以删除 和 INP_KEY = '?'
谓词并将其进一步简化为:
select coalesce(a_key,b_key,c_key)
from KEY_TAB
where coalesce(a_key,b_key,c_key) = :2
and KEY_TAB_KEY = :3
特别是因为您已经在上面的 coalesce(a_key,b_key,c_key)
上创建了索引。
关于Oracle 基于函数的索引和 CASE 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32489310/