如何加速此SQL查询?

如何加速此SQL查询?,sql,performance,Sql,Performance,在这种情况下,, 我正在尝试从我的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(i

在这种情况下,, 我正在尝试从我的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

有什么提示吗?

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

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

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

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

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


另一个类似的问题是:

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

我认为您必须索引:

  • ex1.ib_id
  • ex1.state\u类型
  • ib1.cons\u id
  • ex1.exu id
  • ib1.reg_时间
另外,避免在查询条件中使用函数,尽量直接放入函数的结果

  • 如有可能,将截止日期(“2009-01-01”、“YYYY-MM-DD”)替换为结果
  • trunc(ib1.reg_time),尝试存储已经“trunc”的ed值
然后,像Ingo的回答中所说的那样加入,以便更好地控制加入

最后,您按ib1.id对结果进行排序,有必要吗?如果没有,请删除order子句

查看Oracle的文档,它是关于查询分析的。

mysql workbench
与Oracle的配合不太好。问题是关于oracle@djleop当前位置我知道这是为Oracle准备的。但是,任何RDBMS的基本概念都是相同的。下面是一个关于如何在oracle中分析查询的文档:尝试将
trunc(ib1.reg\u-time)
替换为
ib1.reg\u-time
(只是为了澄清,如果您将限制调整为使用
,则不需要
trunc
)对常量值或参数使用函数(如
to_date()
)不是问题。在列上使用函数,如
trunc()
,是一个严重的问题。to_date()可以,但我认为这是一个可能的优化。您可以将该条件替换为
和(ib1.reg_time>=date'2009-01-01'和ib1.reg_time
,它们可能使用索引,并且不会调用
trunc()
函数的次数达到了万亿次。这显然是错误的。虽然出于其他原因,使用显式的
JOIN
语法是好的,但就效率而言,它无关紧要。如果你有一个非常糟糕的计划者,我想这可能会有所不同,但对于任何半体面的计划者,显式与交叉连接和过滤器将被视为等价的。因为这是甲骨文,我们可以排除这种可能性。同意你的两个意见。基本上,rdbms的优化器通常将这两种查询优化为同一个执行计划。。。从理论上讲,如果他们不进行优化,这将产生不同,但正如您所指出的,现在任何主要的rdbms都应该适当地处理这个问题