我的问题涉及Oracle 11g和在SQL查询中使用索引。在我的数据库中,有一张表结构如下:
我已经创建了两个索引:
很遗憾,尽管我创建了上述两个索引,但查询需要约1小时才能执行。解释计划显示Oracle使用了“表全访问”,即全表扫描。为什么没有使用索引?
作为实验,我测试了以下SQL命令:
即使在这种情况下,索引也没有被使用,会执行完整的表扫描。
在我的真实数据库中,表包含更多的索引列,如“dynamic_col_1”和“dynamic_col_1_text”。整个索引文件的大小约为50GB。
一些更多的信息:
- 数据库是安装在我的本地计算机上的Oracle 11g。 - 我使用的是Windows 7 Enterprise 64位。 - 整个索引分为3个dbf文件,大小约为50GB。
如果有人能告诉我如何使Oracle在第一个查询中使用索引,我将不胜感激。因为第一个查询被另一个程序用于从数据库中提取数据,很难进行更改。因此,调整表格会很好。
提前致谢。
[01.10.2011:更新]
我认为我已经找到了这个问题的解决方案。两列
Table tab (
rowid NUMBER(11),
unique_id_string VARCHAR2(2000),
year NUMBER(4),
dynamic_col_1 NUMBER(11),
dynamic_col_1_text NVARCHAR2(2000)
) TABLESPACE tabspace_data;
我已经创建了两个索引:
CREATE INDEX Index_dyn_col1 ON tab (dynamic_col_1, dynamic_col_1_text) TABLESPACE tabspace_index;
CREATE INDEX Index_unique_id_year ON tab (unique_id_string, year) TABLESPACE tabspace_index;
包含大约1到2百万条记录。我通过执行以下SQL命令从中提取数据:SELECT distinct
"sub_select"."dynamic_col_1" "AS_dynamic_col_1","sub_select"."dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM
(
SELECT "tab".* FROM "tab"
where "tab".year = 2011
) "sub_select"
很遗憾,尽管我创建了上述两个索引,但查询需要约1小时才能执行。解释计划显示Oracle使用了“表全访问”,即全表扫描。为什么没有使用索引?
作为实验,我测试了以下SQL命令:
SELECT DISTINCT
"dynamic_col_1" "AS_dynamic_col_1", "dynamic_col_1_text" "AS_dynamic_col_1_text"
FROM "tab"
即使在这种情况下,索引也没有被使用,会执行完整的表扫描。
在我的真实数据库中,表包含更多的索引列,如“dynamic_col_1”和“dynamic_col_1_text”。整个索引文件的大小约为50GB。
一些更多的信息:
- 数据库是安装在我的本地计算机上的Oracle 11g。 - 我使用的是Windows 7 Enterprise 64位。 - 整个索引分为3个dbf文件,大小约为50GB。
如果有人能告诉我如何使Oracle在第一个查询中使用索引,我将不胜感激。因为第一个查询被另一个程序用于从数据库中提取数据,很难进行更改。因此,调整表格会很好。
提前致谢。
[01.10.2011:更新]
我认为我已经找到了这个问题的解决方案。两列
dynamic_col_1
和dynamic_col_1_text
都是可空的。在更改表以禁止这两列的“NULL”值,并仅为列year
添加一个新索引后,Oracle执行快速索引扫描。优点是查询现在只需要大约5秒钟就可以执行,而不是之前的1小时。
rowid
字段是主键吗? - Bogdan Sahlean