我如何加快这个SQL查询?

时间:2013-02-15 08:43:08

标签: sql performance

这里的情况, 我试图从我的Oracle数据库生成一个包含大量行的报告,我现在有大约5分钟的查询时间,并想知道是否有任何方法可以改变查询,这可能会加快查询时间,

SELECT ib1.id as InvoiceNumber,
ib1.shipmentno as ShipmentNumber,
ib1.ref as ConsignorRef, 
cons1.name as ConsName,
ib1.consolidation_type as ShipmentType, 
to_char(ib1.custom_field12, 'YYYYMMDDhhmmss') as InvoiceDate, 
ib1.reg_time as HousingDate, 
ib1.list_add_time as Pickup, 
ib1.confirm_date as Date, 
ex1.stat_date as Timestamp, 
ib1.date_prefered as ETA, 
ib1.field7 as Housing, 
ib1.countrycode as Country
FROM Invoice ib1,
     ek_export ex1,
      ek_cons cons1
WHERE ib1.ex_id=124
AND ib1.id=ex1.ib_id
AND ex1.state_type='DELIVERED'
AND ib1.cons_id=cons1.id
AND ex1.ex_id=124
AND trunc(ib1.reg_time) BETWEEN to_date('2009-01-01', 'YYYY-MM-DD') AND to_date('2010-01-01', 'YYYY-MM-DD')
ORDER BY ib1.id

任何提示?

4 个答案:

答案 0 :(得分:5)

您必须检查您的查询是否使用索引。

我认为你必须索引:

  • ex1.ib_id
  • ex1.state_type
  • ib1.cons_id
  • ex1.ex_id
  • ib1.reg_time

另外,在查询条件中避免使用函数,尝试直接放置函数的结果

    如果可能,
  • to_date('2009-01-01','YYYY-MM-DD')替换为结果
  • trunc(ib1.reg_time),尝试存储已经“截断”的ed值

然后,按照Ingo的回答说出你的联接,以便更好地控制你的联接。

最后,您通过ib1.id订购结果,是否有必要?如果没有,请删除订单条款。

查看Oracle的这份文档,它是关于查询的分析。 http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm

答案 1 :(得分:2)

您需要分析查询。您可以查看执行计划,还可以查看在每个参与表上创建的索引。

拇指规则是应该在参与where子句和order by子句的列上创建索引。

另一个类似的问题是:Making my SQL Query more efficient

答案 2 :(得分:0)

有一个查询步骤,查询本身和提取,我认为提取不能被压缩。你能说出每个步骤的时间吗? (mysql-worbench给出两种信息)

答案 3 :(得分:0)

您的查询首先对所有表进行交叉连接,然后在where子句中过滤大量结果...使用内部联接仅选择首先重要的行...例如

...
from invoice ib1 
join ek_export ex1 on ib1.id = ex1.ib_id
join ek_cons cons1 on ib1.cons_id = cons1.id
...