Select pinv.pipeline_ref_id Invoice_No,
pinv.orig_company_id Company,
pinv.orig_terminal_id Terminal,
phwb.pipeline_ref_id HWB_No,
ih.transport_mode Trans_Mode,
ih.import_export_ind Business_Type,
to_date(ms.accounting_date,'dd/mm/yy') BL_Confirm_date,
to_date(sf_get_local(pinv.pipeline_tx_status_date,pinv.status_date_tz_code),'dd/mm/yy') Inv_Void_Date,
(pinv.pipeline_tx_status_date - ms.accounting_date) BL_Days, ih.billto_name BillTo_Name, ppi.partner_id BillTo_ID,
pinv.last_modified_by Executed_By, ih.oc_invoice_amt Invoice_Amount
From pipeline pinv
JOIN invoice_header ih ON pinv.pipeline_tx_id = ih.pipeline_tx_id
JOIN pipeline_relations prin ON pinv.pipeline_tx_id = prin.pipeline_tx_id
JOIN pipeline phwb ON prin.rel_pipeline_tx_id = phwb.pipeline_tx_id
JOIN multisegment_status ms ON phwb.pipeline_tx_id = ms.pipeline_tx_id
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
Where
(TRUNC(sf_get_local(pinv.pipeline_tx_status_date,pinv.status_date_tz_code)) between to_date('&1','DD-MON-YYYY:HH24:MI:SS') AND to_date('&2','DD-MON-YYYY:HH24:MI:SS'))
我是Oracle的新手。 对于1小时数据获取,SQL需要几个小时。请你检查一下我做错了什么。
还有一件事是如何运作的:
TRUNC(sf_get_local(pinv.pipeline_tx_status_date,pinv.status_date_tz_code)) between to_date('&1','DD-MON-YYYY:HH24:MI:SS') AND to_date('&2','DD-MON-YYYY:HH24:MI:SS')
谢谢, fuko
答案 0 :(得分:3)
究竟是如何运作的
sf_get_local()
是应用程序中的一个函数,而不是Oracle内置的函数,因此您可以查看其来源以确定它的作用,但我们不能。但是,我猜它会将UTC中的时间戳转换为本地时区。 trunc()
删除了时间元素,因此2018-05-08 15:20:01.542
将变为2018-05-08
,这似乎有点奇怪,因为操作数以日期时间格式表示为秒。
至于为什么“SQL花费数小时”,我们很难说。性能诊断需要更多细节。解释计划会有所帮助。 Find out more.
明显的事情要看:
WHERE
子句可能不使用索引(除非你在pipeline(trunc(sf_get_local(pipeline_tx_status_date,status_date_tz_code))
上有一个基于函数的索引。问题是你是在过滤日期因此,优化器很难判断使用索引是一件好事。如果范围是一小时而你正在扫描五年的数据,那么索引是有用的。但是如果范围跨越一年并且你不是有五年的数据。
您正在查看一小时的数据,因此您可能会从构建基于函数的索引中获得一些好处。 Find out more
此联接实际上是一个CROSS JOIN :
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
您不会通过标识符将pipeline_parties
加入查询中的任何其他表。这意味着您的结果集将是pipeline_parties
中partner_role = 'BT'
所有行中所有其他行的乘积。也许这只是一行,在这种情况下你应该明确关于CROSS JOIN。否则,返回的数据超出了您的需要可能是查询需要时间的另一个原因。
您的某些联接看起来像这样:
JOIN multisegment_status ms ON phwb.pipeline_tx_id = ms.pipeline_tx_id
但是一切都来自pipeline
。您可以通过将所有子表连接到该表来帮助优化器做出更明智的决策:
JOIN multisegment_status ms ON pinv.pipeline_tx_id = ms.pipeline_tx_id
请注意,您再次在此处生成产品。除非所有其他表与pipeline
具有一对一的关系,否则您将生成所有选定记录的排列。可能这不是你想要的。
此时我们必须指出这是您的数据模型和业务规则。您需要了解您正在实施的逻辑以及数据如何符合该逻辑。这意味着您需要了解数据模型中表之间的关系。
答案 1 :(得分:0)
假设您已准备好索引来帮助JOIN
s,那么下一个最好看的地方就是WHERE
子句。
理想情况下,您不应将搜索列放在函数中。将搜索列放在函数中可防止其索引被有效使用。 (在网上搜索SARGable
。)例如,如果您有合适的索引,此处的第一个代码段可以比第二个代码段运行得快......
WHERE
myTable.dateColumn >= TRUNC(to_date('&1','DD-MON-YYYY:HH24:MI:SS'))
AND myTable.dateColumn < TRUNC(to_date('&2','DD-MON-YYYY:HH24:MI:SS')) + INTERVAL '1' DAY
Vs
WHERE
TRUNC(myTable.dateColumn) BETWEEN to_date('&1','DD-MON-YYYY:HH24:MI:SS')
AND to_date('&2','DD-MON-YYYY:HH24:MI:SS')
仍然留下函数调用:
sf_get_local(pinv.pipeline_tx_status_date,pinv.status_date_tz_code)
您应该在其上放置一个基于函数的索引,以便可以对函数调用的结果建立索引。
然后你需要开始查看解释计划。确定计划的哪一部分是最昂贵的,并解决这些特定部分。 (如果你在你的问题中包含解释计划,它甚至会有所帮助。)