Oracle 中的功能索引交叉引用
我有两个这样的表
create table A_DUMMY (
TRADE_ID VARCHAR2(16)
TRADE_DATA VARCHAR2(500)
)
create table B_DUMMY (
EXT_TRADE_ID VARCHAR2(16)
EXT_DATA VARCHAR2(250)
)
并且有一个构建类似的视图
CREATE OR REPLACE VIEW DUMMY_VIEW("TRADE_DATA", "EXT_DATA")
AS
SELECT A.TRADE_DATA, B.EXT_DATA FROM A_DUMMY A, B_DUMMY B
WHERE
GET_TRADE_NUMBER(A.TRADE_ID,'-') = GET_TRADE_NUMBER(B.EXT_TRADE_ID,'_')
OR
GET_TRADE_NUMBER(A.TRADE_ID,'-') = B.EXT_TRADE_ID
为了优化它,我在 A_DUMMY 中的 TRADE_ID 和 B_DUMMY 中的 EXT_TRADE_ID 上创建了功能索引。
该函数如下所示:
create or replace function
GET_TRADE_NUMBER(trade in varchar2, separator in varchar2)
return varchar2
deterministic
as
begin
return SUBSTR(trade, 0, INSTR(trade, separator, 1, 1) - 1);
end;
功能索引如下所示
create index A_DUMMY_IDX ON A_DUMMY(GET_TRADE_NUMBER(TRADE_ID,'-'));
create index B_DUMMY_IDX ON B_DUMMY(GET_TRADE_NUMBER(EXT_TRADE_ID,'_'));
数据如下所示:
INSERT INTO a_dummy VALUES ('7874-LND', 'item1');
INSERT INTO a_dummy VALUES ('7845-NY', 'item2');
INSERT INTO a_dummy VALUES ('7844-NY', 'item3');
INSERT INTO b_dummy VALUES ('7844', 'item4');
INSERT INTO b_dummy VALUES ('7845_LND', 'item5');
INSERT INTO b_dummy VALUES ('7874_LND', 'item5');
如何让 Oracle 在为 DUMMY_VIEW 提供的查询中使用此索引?
因为,看起来,无论我按照解释计划做什么,Oracle 都会忽略它们。
I have two tables like this
create table A_DUMMY (
TRADE_ID VARCHAR2(16)
TRADE_DATA VARCHAR2(500)
)
create table B_DUMMY (
EXT_TRADE_ID VARCHAR2(16)
EXT_DATA VARCHAR2(250)
)
And have a view that is build something like this
CREATE OR REPLACE VIEW DUMMY_VIEW("TRADE_DATA", "EXT_DATA")
AS
SELECT A.TRADE_DATA, B.EXT_DATA FROM A_DUMMY A, B_DUMMY B
WHERE
GET_TRADE_NUMBER(A.TRADE_ID,'-') = GET_TRADE_NUMBER(B.EXT_TRADE_ID,'_')
OR
GET_TRADE_NUMBER(A.TRADE_ID,'-') = B.EXT_TRADE_ID
To optimize this I created a functional index on TRADE_ID in A_DUMMY and EXT_TRADE_ID in B_DUMMY.
The function looks like this:
create or replace function
GET_TRADE_NUMBER(trade in varchar2, separator in varchar2)
return varchar2
deterministic
as
begin
return SUBSTR(trade, 0, INSTR(trade, separator, 1, 1) - 1);
end;
Functional indexes look like this
create index A_DUMMY_IDX ON A_DUMMY(GET_TRADE_NUMBER(TRADE_ID,'-'));
create index B_DUMMY_IDX ON B_DUMMY(GET_TRADE_NUMBER(EXT_TRADE_ID,'_'));
Data looks like this:
INSERT INTO a_dummy VALUES ('7874-LND', 'item1');
INSERT INTO a_dummy VALUES ('7845-NY', 'item2');
INSERT INTO a_dummy VALUES ('7844-NY', 'item3');
INSERT INTO b_dummy VALUES ('7844', 'item4');
INSERT INTO b_dummy VALUES ('7845_LND', 'item5');
INSERT INTO b_dummy VALUES ('7874_LND', 'item5');
How can I make Oracle use this indexes in provided query for DUMMY_VIEW?
Because, it seems, what ever I do according to explanation plan Oracle ignores them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果没有示例数据和函数的详细信息,很难诊断为什么 Oracle 不使用基于函数的索引。
我将演示一个使用索引的情况:
通过此设置,我们注意到索引用于简单查询:
..但不幸的是不用于您的示例查询。 OR 运算符可能会阻止优化器使用索引。我建议您使用等效的查询:
作为旁注:您要不使用过滤器连接两个表,不带索引的 HASH 连接可能是计算连接的最快方法。 完整扫描不是总是邪恶的,索引并不总是好的。
without sample data and the details of the function it is hard to diagnose why Oracle doesn't use your function-based indexes.
I will demo a case where the index is used:
With this setup we notice that the index is used with simple queries:
.. but unfornately not with your example query. The
OR
operator may prevent the optimizer from using the indexes. I suggest you use an equivalent query:As a side note: you are joining the two tables Without filter, a HASH join without index is perhaps the fastest way to compute the join. Full scans are not always evil, indexes are not always good.