2

在这种情况下,我试图从我的 Oracle DB 中生成一个包含很多行的报告,我现在有大约 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

4 回答 4

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),尝试存储已经“截断”的值

然后,像 Ingo 的回答中所说的那样进行连接,以便更好地控制您的连接。

最后,你按 ib1.id 排序你的结果,有必要吗?如果不是,请删除 order 子句。

Check at this documentation of Oracle, it's about analysis of query. http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm

于 2013-02-15T08:53:02.827 回答
2

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

经验法则是应该在参与 where 子句和 order by 子句的列上创建索引。

另一个类似的问题在这里:让我的 SQL 查询更高效

于 2013-02-15T08:49:01.410 回答
0

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

于 2013-02-15T08:46:12.217 回答
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
...
于 2013-02-15T08:48:43.790 回答