与过程/函数中的高效 DML 相关的问题

发布于 2024-12-19 10:37:44 字数 755 浏览 1 评论 0原文

我有两个关于执行 DML 时 PL/SQL 脚本性能的问题。当然,EXECUTE IMMEDIATE 是最慢的,这就是为什么我们有 forallbulk insert 等。我的问题是

  1. 我必须以 3 种不同的方式操作数据表。 Table1(插入数据)、Table2(更新数据)和Table3删除数据。所有这些都将根据使用游标获取的值来完成。问题是这里什么会更有效率?
    • 将这些语句中的每一个放入单独的 Forall 块中?即
获取游标
环形
   表 1 的 forall 循环
   表 2 的 forall 循环
   表 3 的 forall 循环
结束循环

OR

  • 全局循环并在该循环中执行这些语句,即
获取游标循环
    for i IN array.count 
    环形
       3条DML语句
    循环结束 循环结束

现在我的第二个问题

  1. 是什么是删除循环中记录的有效方法?我通过游标获取了要删除的记录的值。现在删除它们的有效方法是什么?

附: 执行我的格式化

I have 2 questions regarding performance of PL/SQL script when executing DML. Ofcourse the EXECUTE IMMEDIATE is the slowest one thats why we have forall, bulk insert etc. My Questions are

  1. I have to manipulate data in 3 different tables. Table1 (insert data), Table2(update data) and Table3 delete data. All of these would be done based on the values fetched using a cursor. the question is what would be more efficient here?
    • Putting each of these statements in individual Forall block? i.e.
fetch cursor
loop
   forall loop for table 1
   forall loop for table 2
   forall loop for table 3
end loop

OR

  • a global loop and execute these statments in that loop i.e.
fetch cursor loop
    for i IN array.count 
    loop
       3 statements for DML
    end loop end loop

Now my second question

  1. what is the efficient way to delete records in loop? I fetched the values of the records to be deleted through the cursor. now what would be the efficient way to delete them?

P.S:
Execuse my formatting

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

微凉 2024-12-26 10:37:44

最有效的方法是编写三个 SQL 语句,假设从游标获取的数据在过程运行期间保持稳定,

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

如果 SELECT 语句可能会在每个语句中返回不同的结果三个 DML 语句,那么接受使用游标、将数据批量收集到 PL/SQL 集合并循环遍历集合以确保结果一致的性能影响是有意义的。如果您正在这样做,那么使用三个 FORALL 语句会更有效,因为这会减少 SQL 和 PL/SQL 引擎之间的上下文转换。

循环删除记录的有效方法是什么?我通过游标获取了要删除的记录的值。现在删除它们的有效方法是什么?

我不确定我是否理解这个问题。您不会像执行 INSERT 或 UPDATE 一样执行 FORALL 循环吗?

FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

或者您是否在问不同的问题?

The most efficient approach would be to write three SQL statements, assuming the data fetched from the cursor is stable over the period of time that the procedure is running

INSERT INTO table1( list_of_columns )
  <<your SELECT statement>>

UPDATE table2
   SET (<<list of columns>>) = (<<your SELECT statement joined to table2>>)
 WHERE EXISTS( <<your SELECT statement joined to table2>> );

DELETE FROM table3
 WHERE EXISTS( <<your SELECT statement joined to table3>> );

If the SELECT statement will potentially return different results in each of the three DML statements, then it makes sense to accept the performance hit of using a cursor, bulk collecting the data into PL/SQL collections, and looping over the collections in order to ensure consistent results. If that's what you're doing, it will be more efficient to have three FORALL statements since that involves fewer context shifts between the SQL and PL/SQL engines.

What is the efficient way to delete records in loop? I fetched the values of the records to be deleted through the cursor. now what would be the efficient way to delete them?

I'm not sure I understand the question. Wouldn't you just do a FORALL loop just as you would for an INSERT or an UPDATE

FORALL i IN l_array.first .. l_array.last
  DELETE FROM some_table
   WHERE some_key = l_array(i);

Or are you asking a different question?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文