0
SELECT
/*+ INDEX(ID_BL_REF_NO REF_number_BL_idx*/ DECODE(BL_TYPE,'E',BL_ORIGIN_NAME,'I',BL_FINAL_NAME) FROM_PORT,
 DECODE(BL_TYPE,'I',BL_ORIGIN_NAME,'E',BL_FINAL_NAME) TO_PORT,
(BL_VESSEL_CONNECT||'/'||BL_VOYAGE_CONNECT||'/'||BL_PORT_CONNECT) Mother_vessel_voyage_port,
SUM(BLC_SIZE) No_of_20s,
SUM(BLC_SIZE)  No_of_40s,
SUM(DECODE(BLC_SIZE,'20',1,'40',2)) Teus,
SUM(BLC_GROSSWT) GrossWt,
round((BLC_GROSSWT/SUM(DECODE(BLC_SIZE,'20',1,'40',2))),2) AverageWt,
SUM(DECODE(BLF_MODE,'P',BLF_LOCAL_AMOUNT)) PREPAID,
SUM(DECODE(BLF_MODE,'C',BLF_LOCAL_AMOUNT)) COLLECT,
SUM(DECODE(BLF_MODE,'E',BLF_LOCAL_AMOUNT)) ELSEWHERE,
(SUM(DECODE(BLF_MODE,'P',BLF_LOCAL_AMOUNT)+DECODE(BLF_MODE,'C',BLF_LOCAL_AMOUNT)+DECODE(BLF_MODE,'E',BLF_LOCAL_AMOUNT))/SUM(DECODE(BLC_SIZE,'20',1,'40',2))) AVERAGE
FROM ID_BL_DETAILS,id_bl_containers,ID_BL_FREIGHT
WHERE BL_REFNO=BLC_REFNO
AND BLF_REFNO=BLC_REFNO
GROUP BY BL_VESSEL_CONNECT,BL_VOYAGE_CONNECT,BL_PORT_CONNECT,BL_ORIGIN_NAME,BL_LODPORT,BL_DISPORT,BL_FINAL_NAME,BLC_GROSSWT,BL_TYPE
4

3 回答 3

5

您的 WHERE 子句仅包含连接。没有过滤器。这意味着您的查询需要考虑至少一个表中的所有行。由此可见,您的查询应该对至少一个表执行全表扫描,而不是索引读取。全表扫描是获取表中所有行的最有效方法。

所以不要修复你的 INDEX 提示的语法,去掉它。

接下来,确定哪个表应该驱动您的查询。这是业务逻辑。可能您的要求类似于

“总结 BL_CONTAINERS 中每一行的 BL_DETAILS 和 BL_FREIGHT。”

在这种情况下,您可能认为需要对 BL_CONTAINERS 进行全表扫描。但是,如果 BL_FREIGHT 的行数比 BL_CONTAINERS 多,并且每个 BLF_REF_NO 都匹配一个 BL_REF_NO(即 BL_FREIGHT.BLF_REF_NO 上有一个引用 BL_CONTAINERS.BL_REF_NO 的外键),那么从 BL_FREIGHT 驱动可能会更好。

请注意,如果您只对具有匹配 BL_FREIGHT 行的 BL_CONTAINERS 感兴趣,则这是正确的。但是,如果您想包含尚未使用的容器(即它们没有匹配的 BL_FREIGHT 记录),您需要使用外连接并驱离 BL_CONTAINERS 表。

当您将 BL_DETAILS 混入其中时,这些考虑会变得更加复杂。您的报告似乎基于 BL_DETAILS 类别(正如 Jeffrey 观察到的,我们很难在没有别名或描述的情况下理解您的查询)。所以也许 BL_DETAILS 是驱动表的正确候选者。

如您所见,调优需要深入了解业务逻辑和数据模型的细节。你有当地的知识,我们没有。

有一些工具可以帮助你。Oracle 有解释计划,它将向您展示数据库将如何执行查询。每个版本的查询优化器都会变得更好,因此您使用的数据库版本很重要。这是10g 的文档

需要注意的重要一点是,您需要为数据库提供准确的统计信息,以便它提出一个好的计划。 了解更多。

于 2011-03-11T08:03:50.017 回答
2

Your question states that the query takes 9.968 seconds and you want it to be 0.5 seconds or less. This can only be done effectively (if possible at all) when you know where those 9.968 seconds are spent on. And to know where time in a query is being spent, you'll not only want to explain the statement, you'll want to trace an execution of that query. The latter will give you a breakdown of how the time in your query is spent.

There are two threads on OTN that describe how you can do that.

If you want to do the bare minimum, please follow this one: http://forums.oracle.com/forums/thread.jspa?messageID=1812597

And if you want to give full details, please follow this one: http://forums.oracle.com/forums/thread.jspa?threadID=863295

Happy tracing!

Regards,
Rob.

于 2011-03-11T09:54:12.397 回答
2

在您的查询上运行explain并确保设置了正确的索引。会提高查询速度

http://www.sql.org/sql-database/postgresql/manual/sql-explain.html

于 2011-03-11T03:02:27.853 回答