Where子句使我的查询从2秒减慢到24秒

时间:2013-06-20 22:42:21

标签: sql oracle11g

我正在尝试编写一个简单的查询来计算大表的结果。

SELECT COUNT(*)
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3
WHERE (AL3.REFERENCE_YEAR(+)   =2012)

以上查询大约需要24秒才能返回输出。如果我删除where子句并执行相同的查询,它会在2秒后给我结果。

我可以知道是什么原因造成的。我对SQL查询比较陌生。

请帮忙

谢谢, 纳温

2 个答案:

答案 0 :(得分:1)

您可能需要表格上的索引。通常,您需要在where子句

中使用的任何列上使用索引

关于(+)语法我觉得它是多余的(我不是Oracle专家),但请参阅Difference between Oracle's plus (+) notation and ansi JOIN notation?

答案 1 :(得分:0)

原因可能看起来很微妙。但是Oracle可以通过多种方式处理这样的查询:

SELECT COUNT(*)
FROM DM.DM_CUSTOMER_SEG_BRIDGE_CORP_DW AL3

一种方法是读取表中的所有行。因为这是一张大桌子,所以这不是最有效的方法。第二种方法是使用某种统计信息,其中行数在统计信息中。我认为Oracle不会这样做,但可以想象。

最后一种方法是读取索引。通常,索引会比表小得多,因为它可能已经存在于内存中。上述查询将读取更少量的数据。 (Here是一篇关于计算表中所有行的有趣文章。)

当您引入where子句时,

WHERE (AL3.REFERENCE_YEAR(+)   =2012)

Oracle无法再扫描任何索引。它必须扫描reference_year索引。问题是什么?如果它扫描索引,它仍然需要获取数据记录以获得reference_year的值 - 这相当于(实际上更糟)扫描整个表。

即使reference_year上有索引,也不能保证使用索引。问题是所谓的 selective 。相对于数据库中的行数(在此上下文中,10%是“非常大”),您获取的行数可能仍然非常大。 Oracle优化可以选择执行全表扫描而不是读取索引。