2013-01-13 23 views
2

我有一个表Orders存储订单,与字段:优化SQL查询:过滤未编制索引的字段

Id   
Date   
Amount  
Cost 
Currency 

我尝试以下查询:

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

现在,根据甲骨文的SQL开发者,查询缓慢的原因是Currency = 'EUR'过滤器,因为其他操作的成本更低。

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

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

从一般的观点来看,是否有可能在已经按日期过滤记录之后阻止DBMS执行全表扫描,而是在已经过滤的记录中找到与Currency相匹配的记录日期?

非常感谢

+3

你能告诉我们执行计划吗? –

+0

Oracle显然只会扫描应用以前的过滤器后留下的记录的子集。 1.你为什么认为它正在进行全面扫描? 2。你为什么认为它是先按日期过滤? – Bulat

+1

向我们展示执行计划(以格式化文本发布,不是屏幕截图) –

回答

0

建立在Currency场或复合索引的索引上DateCurrency如果你经常筛选使用这两个领域

+0

好点,但不幸的是,这不是一个选项! –

+3

对不起,但只是出于好奇,什么阻止你这样做? – peterm

2

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

它不扫描整个表格。

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

要解决这个问题,你就需要在(Currency, Date)

创建一个综合指数如果在创建另一个指标是不是一种选择,您可以尝试创建一个MATERIALIZED VIEW并创建一个索引。

0

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

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