【发布时间】:2018-08-29 03:38:44
【问题描述】:
我使用的是 Oracle DB(Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production),我的表定义是这样的:
Create table CardInfo (
Id Number not null,
BalanceInfo Decimal,
...
...
);
很多时候这个表会被这样查询:
select Id, ... from CardInfo where BalanceInfo > 0;
所以,我正在尝试创建一个这样的基于函数的索引:
CREATE INDEX balance_ix ON CardInfo (BalanceInfo > 0);
但是,上面的语句给出了以下错误:
从第 1 行开始的错误命令 -
CREATE INDEX balance_ix ON CardInfo (BalanceInfo > 0);
错误报告 -
ORA-00907: 缺少右括号
00907. 00000 - “缺少右括号”
原因:
行动:
所以我将我的创建索引语句更改为:
CREATE INDEX balance_ix ON CardInfo (BalanceInfo);
这执行得很好并创建了索引。但是,当我像这样为我的 sql 语句执行 Explain Plan 时:
EXPLAIN PLAN
SET statement_id = 'ex_plan1' FOR
SELECT * FROM CardInfo WHERE BalanceInfo > 0;;
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan1','BASIC'));
它产生了以下输出:
计划哈希值:97071123
-------------------------------------------
| Id | Operation | Name |
-------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| CardInfo |
-------------------------------------------
这意味着它没有使用我创建的索引。
有人可以帮忙吗,我怎样才能创建一个索引以便我的 sql 语句使用它? 提前致谢。
【问题讨论】:
-
BalanceInfo 似乎是一个数字列,因为您将它与零进行比较。为什么不使用普通索引来索引 BalanceInfo?在 CardInfo(BalanceInfo) 上创建索引 CardInfoIdx;如果您有大量满足 BalanceInfo > 0 的值,则 FTS 优于 Index Scan。
-
Wernfried Domscheit 的回答中隐藏了您问题的简短答案。即:假设大部分时间里相对较高比例的余额大于零(因为它们在现实生活中),你总是会得到全表扫描。为什么?因为当表中相对较大的部分(例如,超过 20%)的行满足 WHERE 子句时,使用索引的效率。
标签: database oracle indexing oracle12c