优化Sql查询:过滤未编制索引的字段

时间:2013-01-13 00:32:21

标签: sql oracle rdbms

我有一个存储订单的表Orders,其中包含字段:

Id          
Date        
Amount      
Cost
Currency

我尝试了以下查询:

SELECT SUM(Amount)-SUM(NFC1)
FROM Orders
WHERE Date BETWEEN '20121101' AND '20121231'
      AND Currency = 'EUR'

现在,根据Oracle SQL Developer,查询速度慢的原因是Currency = 'EUR'过滤器,因为其他操作的成本要低得多。

我检查了索引,我在Id上有一个索引,在Date上有另一个索引。 在我看来,通过查询分析,DBMS首先找到与所需日期匹配的记录,然后扫描整个表以查找具有Currency='EUR'的记录。 CurrencyVARCHAR

有没有办法优化查询?我的意思是,有没有办法避免全面扫描?

从一般的角度来看,是否可以防止DBMS在按日期过滤记录后执行全表扫描,而是找到与已经过了Currency的记录匹配的记录是按日期过滤的?

非常感谢

3 个答案:

答案 0 :(得分:2)

  

在我看来,通过查询分析,DBMS首先找到与所需日期匹配的记录,然后扫描整个表以查找Currency ='EUR'的记录。货币是VARCHAR。

它不扫描整个表格。

相反,它从索引记录中获取行指针(rowidPRIMARY KEY值,如果表是IOT)并在嵌套循环中查找表行中的货币。由于您使用的索引不包含Currency,因此需要以某种方式查找它以进行过滤。

要解决此问题,您需要在(Currency, Date)

上创建复合索引

如果不能创建另一个索引,您可以尝试创建MATERIALIZED VIEW并在其上创建索引。

答案 1 :(得分:0)

如果您经常使用这两个字段进行过滤,则在Currency字段或DateCurrency上的复合索引上构建索引

答案 2 :(得分:0)

  

有没有办法优化查询?我的意思是,有没有办法避免全面扫描?

完整扫描可能只是可用的最优化计划。通过全面扫描表格,通常可以更快地从表格的大部分过滤数据。数据库可以使用快速,顺序的磁盘读取。