执行SQL需要时间
我是甲骨文的新手。 SQL甚至需要数小时才能获取1小时的数据。你能检查一下我做错了什么吗 还有一件事,它到底是如何工作的:执行SQL需要时间,sql,oracle,performance,query-optimization,Sql,Oracle,Performance,Query Optimization,我是甲骨文的新手。 SQL甚至需要数小时才能获取1小时的数据。你能检查一下我做错了什么吗 还有一件事,它到底是如何工作的: 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
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'))
谢谢,
福科
它到底是如何工作的
sf\u get\u local()
是应用程序中的一个函数,而不是Oracle内置函数,因此您可以查看它的源代码以了解它的功能和我们的功能。然而,我猜它正在将UTC的时间戳转换为本地时区。trunc()
删除了时间元素,因此2018-05-08 15:20:01.542
将变成2018-05-08
,这似乎有点奇怪,因为操作数是以日期时间格式表示的
至于为什么“SQL需要几个小时”,我们很难说。性能诊断需要更多的细节。一个解释计划会有帮助
显而易见的事情:
WHERE子句可能不使用索引(除非您有一个基于管道的函数索引(trunc(sf\u get\u local(管道发送状态日期、状态日期时间代码))
。问题在于,您正在筛选日期范围,因此优化器很难判断何时使用索引是件好事。如果范围是一小时,而您正在扫描五年的数据,则索引是有用的。但如果范围跨越一年,且您有五年的数据,则索引不是有用的
您正在查看一个小时的数据,因此可能会从构建基于函数的索引中获益
此连接实际上是交叉连接:
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')
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
您不能通过标识符将pipeline\u parties
连接到查询中的任何其他表。这意味着您的结果集将是所有其他行与pipeline\u parties
中的每一行的乘积,其中partner\u role='BT'
。可能这只是一行,在这种情况下,您应该明确说明交叉连接。O因此,返回比您需要的更多的数据可能是查询需要时间的另一个原因
您的某些联接看起来像这样:
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')
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
但是一切都是从管道驱动的。通过将所有子表连接到该表,您可以帮助优化器做出更明智的决策:
JOIN multisegment_status ms ON phwb.pipeline_tx_id = ms.pipeline_tx_id
请注意,这里再次生成产品。除非所有其他表与管道
具有一对一的关系,否则您将生成所有选定记录的排列。这可能不是您想要的
此时,我们必须指出,这是您的数据模型和业务规则。您需要了解正在实现的逻辑以及数据如何符合该逻辑。这意味着您需要了解数据模型中表之间的关系
它到底是如何工作的
sf_get_local()
是应用程序中的一个函数,而不是Oracle内置函数,因此您可以查看其源代码以了解它的功能,但我们不能。不过,我猜它正在将UTC时间戳转换为本地时区。trunc()
删除时间元素,因此2018-05-08 15:20:01.542
将变成2018-05-08
,这似乎有点奇怪,因为操作数是以日期时间格式表示的
至于为什么“SQL需要几个小时”,我们很难说。性能诊断需要更多的细节。解释计划会有所帮助
显而易见的事情:
WHERE
子句可能不使用索引(除非您有一个基于管道的函数索引(trunc(sf\u get\u local(管道发送状态日期、状态日期时间代码))
。问题在于,您正在筛选日期范围,因此优化器很难判断何时使用索引是件好事。如果范围是一小时,而您正在扫描五年的数据,则索引是有用的。但如果范围跨越一年,且您有五年的数据,则索引不是有用的
您正在查看一个小时的数据,因此可能会从构建基于函数的索引中获益
此连接实际上是交叉连接:
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')
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
您不能通过标识符将pipeline\u parties
连接到查询中的任何其他表。这意味着您的结果集将是所有其他行与pipeline\u parties
中的每一行的乘积,其中partner\u role='BT'
。可能这只是一行,在这种情况下,您应该明确说明交叉连接。O因此,返回比您需要的更多的数据可能是查询需要时间的另一个原因
您的某些联接看起来像这样:
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')
JOIN pipeline_parties ppi ON ppi.partner_role = 'BT'
但是一切都是从管道驱动的。通过将所有子表连接到该表,您可以帮助优化器做出更明智的决策:
JOIN multisegment_status ms ON phwb.pipeline_tx_id = ms.pipeline_tx_id
请注意,这里再次生成产品。除非所有其他表与管道
具有一对一的关系,否则您将生成所有选定记录的排列。这可能不是您想要的
在这一点上,我们必须指出这是您的数据模型和业务规则。您需要了解正在实现的逻辑以及数据如何符合该逻辑。这意味着您需要了解数据模型中表之间的关系。假设您已将索引放置到位,以帮助连接,下一步就是查看的最佳位置是WHERE
子句
理想情况下,您不应该将搜索列放在函数中。将搜索列放在函数中会妨碍其索引的有效使用。(在网络中搜索SARGable
)例如,如果您有适当的索引,这里的第一个代码段可以比第二个代码段运行得更快
JOIN multisegment_status ms ON pinv.pipeline_tx_id = ms.pipeline_tx_id
您可能应该在此基础上放置一个基于函数的索引,以便可以对函数调用的结果进行索引
然后你需要开始看解释计划。确定计划的哪一部分