让我们假设您在Oracle中有一个表:
CREATE TABLE person (
id NUMBER PRIMARY KEY,
given_names VARCHAR2(50),
surname VARCHAR2(50)
);
Run Code Online (Sandbox Code Playgroud)
使用这些基于函数的索引:
CREATE INDEX idx_person_upper_given_names ON person (UPPER(given_names));
CREATE INDEX idx_person_upper_last_name ON person (UPPER(last_name));
Run Code Online (Sandbox Code Playgroud)
现在,given_names没有NULL值,但为了参数,last_name做了.如果我这样做:
SELECT * FROM person WHERE UPPER(given_names) LIKE 'P%'
Run Code Online (Sandbox Code Playgroud)
解释计划告诉我它使用索引,但将其更改为:
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%'
Run Code Online (Sandbox Code Playgroud)
它没有.Oracle文档说,只有在满足几个条件时才会使用基于函数的索引,其中一个条件是确保没有NULL值,因为它们没有被索引.
我试过这些问题:
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%' AND UPPER(last_name) IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
和
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%' AND last_name IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,我甚至在last_name上添加了一个索引,但无论我尝试使用全表扫描.假设我无法摆脱NULL值,如何让这个查询使用UPPER(last_name)上的索引?
可以使用索引,尽管优化器可能已选择不将其用于特定示例:
SQL> create table my_objects
2 as select object_id, object_name
3 from all_objects;
Table created.
SQL> select count(*) from my_objects;
2 /
COUNT(*)
----------
83783
SQL> alter table my_objects modify object_name null;
Table altered.
SQL> update my_objects
2 set object_name=null
3 where object_name like 'T%';
1305 rows updated.
SQL> create index my_objects_name on my_objects (lower(object_name));
Index created.
SQL> set autotrace traceonly
SQL> select * from my_objects
2 where lower(object_name) like 'emp%';
29 rows selected.
Execution Plan
----------------------------------------------------------
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 17 | 510 | 355 (1)|
| 1 | TABLE ACCESS BY INDEX ROWID| MY_OBJECTS | 17 | 510 | 355 (1)|
|* 2 | INDEX RANGE SCAN | MY_OBJECTS_NAME | 671 | | 6 (0)|
------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
您阅读的文档可能指出,就像任何其他索引一样,全零键不会存储在索引中.
归档时间: |
|
查看次数: |
47106 次 |
最近记录: |