创建基于函数的索引时缺少括号错误

时间:2014-10-28 16:22:00

标签: sql oracle function indexing

我正在尝试在具有高成本(Oracle)的谓词上创建基于函数的索引。

我想在A4ORDERS表中的TIME_ID列上创建一个索引,该列返回12月份的值:

SELECT * FROM A4ORDERS WHERE TRIM(TO_CHAR(time_id, 'Month')) in ( 'December' );

创建FBI:

CREATE INDEX TIME_FIDX ON A4ORDERS(TRIM(TO_CHAR(time_id, 'Month'))  in ( 'December' ));

我得到一个" Missing Right括号"错误,我无法弄清楚为什么?您可以提供任何指导,我们将不胜感激。

Alex Poole的解决方案及其下面的回复有效:

CREATE INDEX TIME_FIDX ON A4ORDERS (TRIM(TO_CHAR(time_id, 'Month')));

2 个答案:

答案 0 :(得分:2)

您可以使用:

CREATE INDEX TIME_FIDX ON A4ORDERS(TRIM(TO_CHAR(time_id, 'Month')));

但你也可以让它变得更简单:

CREATE INDEX TIME_FIDX ON A4ORDERS(TO_CHAR(time_id, 'mm'));

并编写SQL:

SELECT * FROM A4ORDERS WHERE TO_CHAR(time_id, 'mm') in ( '12');

但是,如果您提供有关您的问题的更多信息(变通方法,SQL查询,计划等),您可以获得更多帮助。

答案 1 :(得分:2)

您的create index语句不应包含in ( 'December' )部分,该部分仅属于查询。如果您将索引创建为:

CREATE INDEX TIME_FIDX ON A4ORDERS (TRIM(TO_CHAR(time_id, 'Month')));

...然后您的查询可以使用该索引:

EXPLAIN PLAN FOR
SELECT * FROM A4ORDERS WHERE TRIM(TO_CHAR(time_id, 'Month')) in ( 'December' );

SELECT plan_table_output FROM TABLE (dbms_xplan.display());

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |    29 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| A4ORDERS  |     1 |    29 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | TIME_FIDX |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):                                      
---------------------------------------------------                                      

   2 - access(TRIM(TO_CHAR(INTERNAL_FUNCTION("TIME_ID"),'Month'))='December')        

因此,您可以从计划中看到正在使用TIME_FIDX。当然,它是否会给你带来显着的性能提升还有待观察,优化者可能会认为它不具备选择性。

'月'但是对NLS敏感;使用月份号码或在TO_CHAR调用中指定NLS_DATE_LANGUAGE会更安全,但必须始终如一地进行 - 这对数字来说会更容易一些。您也可以将其设为索引虚拟列。