【发布时间】:2013-09-26 00:36:31
【问题描述】:
我有一个包含 2.26 亿行的表,其中包含 varchar2(2000) 列。前 10 个字符使用功能索引 SUBSTR("txtField",1,10) 进行索引。
我正在运行这样的查询:
select count(1)
from myTable
where SUBSTR("txtField",1,10) = 'ABCDEFGHIJ';
数据库中不存在该值,所以返回“0”。
解释计划显示执行的操作是“INDEX (RANGE SCAN)”,我假设它的成本是 4。当我运行这个查询时,它平均需要 114 秒。
如果我更改查询并强制它不使用索引:
select count(1)
from myTable
where SUBSTR("txtField",1,9) = 'ABCDEFGHI';
解释计划显示该操作将是一个“TABLE ACCESS (FULL)”,这是有道理的。成本为 629,000。当我运行这个查询时,它平均需要 103 秒。
我试图了解扫描索引可能比读取表中的每条记录并在字段上执行 substr 函数花费更长的时间。
跟进: 表中有230M+行,查询返回17行;我选择了数据库中的一个新值。最初,我使用不在数据库中的值执行并返回零行。好像没什么区别。
查询有关索引的信息会产生: CLUSTERING_FACTOR=201808147 LEAF_BLOCKS=1131660
我正在使用 AUTOTRACE ON 和 gather_plan_statistics 运行查询,并将在这些结果可用时添加它们。
感谢所有建议。
【问题讨论】:
-
之前调用
SET AUTOTRACE ON会有什么输出? -
你能在你的问题中添加你的索引的确切定义吗?
-
"Count(1)" -- 与 count(*) 相同,但不是标准语法。
-
该查询返回多少行,索引的聚类因子是多少?使用多块 IO 读取表的所有块可能比使用单块 IO 读取索引中的许多块更快。您能否添加此查询的结果(确保统计数据是最新的):
select owner, index_name, clustering_factor, num_rows, leaf_blocks from all_indexes where index_name = 'index name';此外,对于查询性能问题,您应该始终使用explain plan for select ...;和select * from table(dbms_xplan.display);发布完整的解释计划。 -
表中有230M+行,查询返回17行。上述查询结果:CLUSTERING_FACTOR=201808147, LEAF_BLOCKS=1131660
标签: sql oracle indexing query-performance