我有一个存储订单的表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'
的记录。 Currency
是VARCHAR
。
有没有办法优化查询?我的意思是,有没有办法避免全面扫描?
从一般的角度来看,是否可以防止DBMS在按日期过滤记录后执行全表扫描,而是找到与已经过了Currency
的记录匹配的记录是按日期过滤的?
非常感谢
答案 0 :(得分:2)
在我看来,通过查询分析,DBMS首先找到与所需日期匹配的记录,然后扫描整个表以查找Currency ='EUR'的记录。货币是VARCHAR。
它不扫描整个表格。
相反,它从索引记录中获取行指针(rowid
或PRIMARY KEY
值,如果表是IOT)并在嵌套循环中查找表行中的货币。由于您使用的索引不包含Currency
,因此需要以某种方式查找它以进行过滤。
要解决此问题,您需要在(Currency, Date)
如果不能创建另一个索引,您可以尝试创建MATERIALIZED VIEW
并在其上创建索引。
答案 1 :(得分:0)
如果您经常使用这两个字段进行过滤,则在Currency
字段或Date
和Currency
上的复合索引上构建索引
答案 2 :(得分:0)
有没有办法优化查询?我的意思是,有没有办法避免全面扫描?
完整扫描可能只是可用的最优化计划。通过全面扫描表格,通常可以更快地从表格的大部分过滤数据。数据库可以使用快速,顺序的磁盘读取。