过程花费太多时间来更新数据库
CREATE OR REPLACE PROCEDURE UPDATE_CRDT_JV IS
BEGIN
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT ADJ_DATE FROM ADJUSTMENTS WHERE
ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'ADJST';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT PARTY_ADJ_DATE FROM PARTY_ADJUSTMENT
WHERE PARTY_ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'PRTAJ';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT VEN_PAY_VOU_DATE FROM PAYMENTS_TO_VENDORS WHERE
VEN_PAY_VOU_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'CRPAY';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT CHEQUE_DATE FROM SYS_PAYMENTS_HEADER WHERE
REF_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'SYSPY';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT POSTED_DATE FROM PURCHASE_INVOICE_HEADER WHERE
POSTED_DATE IS NOT NULL AND PIV_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'CRINV';
UPDATE GL_dISTRIBUTION
SET GL_dATE = (SELECT DOC_dATE FROM REVERSE_HISTORY
WHERE TR_NUMBER = TO_NUMBER(GL_DISTRIBUTION.TR_NUMBER)
AND DOC_dATE IS NOT NULL AND TR_TYPE IN ('SYSPY','CRPAY'))
WHERE TR_TYPE IN ('RSYSPY','RCRPAY');
commit;
UPDATE_INV_DET;
END;
更新数据库需要超过 15 分钟。 现在我正在通过在 SQL PLUS 中使用以下查询来更新此内容:
EXECUTE UPDATE_CRDT_JV;
如果有人知道此问题的解决方案,请帮助我
CREATE OR REPLACE PROCEDURE UPDATE_CRDT_JV IS
BEGIN
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT ADJ_DATE FROM ADJUSTMENTS WHERE
ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'ADJST';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT PARTY_ADJ_DATE FROM PARTY_ADJUSTMENT
WHERE PARTY_ADJ_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'PRTAJ';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT VEN_PAY_VOU_DATE FROM PAYMENTS_TO_VENDORS WHERE
VEN_PAY_VOU_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'CRPAY';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT CHEQUE_DATE FROM SYS_PAYMENTS_HEADER WHERE
REF_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'SYSPY';
UPDATE GL_DISTRIBUTION
SET GL_DATE = (SELECT POSTED_DATE FROM PURCHASE_INVOICE_HEADER WHERE
POSTED_DATE IS NOT NULL AND PIV_NUMBER = TO_NUMBER(TR_NUMBER))
WHERE TR_TYPE = 'CRINV';
UPDATE GL_dISTRIBUTION
SET GL_dATE = (SELECT DOC_dATE FROM REVERSE_HISTORY
WHERE TR_NUMBER = TO_NUMBER(GL_DISTRIBUTION.TR_NUMBER)
AND DOC_dATE IS NOT NULL AND TR_TYPE IN ('SYSPY','CRPAY'))
WHERE TR_TYPE IN ('RSYSPY','RCRPAY');
commit;
UPDATE_INV_DET;
END;
is taking more than 15 minutes to update the database.
now i am updating this by using the following query in SQL PLUS:
EXECUTE UPDATE_CRDT_JV;
pls help me if any body knows the solution for this problem
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我同意已经给出的建议,开始弄清楚你的代码在哪里花费了时间。但是,您的情况很常见,我认为我认识到这种情况:您以这样的方式编码更新语句,以便为该类型的 GL_DISTRIBUTION 的每一行访问其他表。
解决方案是重写您的更新语句,我发现有两种有效地做到这一点的可能性:
1)更新选择语句(UPDATE(SELECT ...)SET ... WHERE ...)。这需要设置一些唯一的键约束或使用 BYPASS_UJVC 提示。
2)使用MERGE语句。
下面您将看到如何使用单个合并语句重写代码的示例。我期望获得巨大的性能提升,因为现在对每个表使用单个外连接即可完成对其他表的访问,而不是对 GL_DISTRIBUTION 表中的每一行进行访问。
例子。测试数据:
您的程序(用于比较):
我的建议:
让我们运行您的程序:
我的程序返回相同的结果:
希望这会有所帮助。
问候,
抢。
I agree with the already given advice to start figuring out where your code is spending time. However, your case is quite common and I think I recognize this situation: you have coded your update statements in such a way that the other tables are accessed for every row of GL_DISTRIBUTION of that type.
The solution is to rewrite your update statements and I see two possibilities to do that efficiently:
1) Update a select statement (UPDATE (SELECT ...) SET ... WHERE ...). This requires some unique key constraints to be in place or using the BYPASS_UJVC hint.
2) Use a MERGE statement.
Below you see an example of how to rewrite your code using a single merge statement. I'm expecting big performance gains because the access of the other tables is now done once using a single outer join for each of the tables, instead of for every row in the GL_DISTRIBUTION table.
The example. Test data:
Your procedure (for comparison):
My suggestion:
Let's run your procedure:
My procedure returns the same results:
Hope this helps.
Regards,
Rob.
这个问题的解决方案是:
花时间(即分析它)
最慢的部分
如果您更喜欢猜测,那么您可能需要尝试以下任一方法:
将多个 UPDATE 合并到单个 UPDATE 语句中,例如使用 @Aklopper 所示的 CASE 条件。
使用 MERGE 而不是 UPDATE 以避免相关子查询。可能会更好,也可能不会。
查看在所示过程末尾调用的 UPDATE_INV_DET 过程。
The solution for this problem is:
spending its time (i.e. profile it)
slowest part
If you prefer guesswork, then you might want to try any of the following:
Combine multiple UPDATEs into a single UPDATE statement, e.g. using a CASE condition as shown by @Aklopper.
Use MERGE instead of UPDATE to avoid correlated subqueries. Might be better, might not.
Look into the UPDATE_INV_DET procedure which is called at the end of the procedure shown.
我来自SQL Server环境,这样的CASE UPDATE语句不会对你有帮助吗(SQL中UPDATE CASE语句的使用示例(不知道Oracle是否有等效的方法):
I come from a SQL Server environment, won't a CASE UPDATE statement like this also help you(example of usage of the UPDATE CASE statement in SQL(don't know if Oracle has an equivalent methods) :