oracle - Oracle中使用临时表优化SQL

标签 oracle performance optimization temp-tables

我有一个数据清理程序,它从两个表的卡行中删除相同的数据。
这两个更新语句都使用相同的子查询来检测应该更新哪些行。

 UPDATE table_1 SET card = NULL WHERE id in
               (select id from sub_table WHERE /* complex clause here */);

 UPDATE table_2 SET card = NULL WHERE id in
               (select id from sub_table WHERE /* complex clause here */);

使用 Oracle 临时表是优化我的代码的好解决方案吗?
CREATE TEMPORARY TABLE tmp_sub_table AS
select id from sub_table WHERE /* complex clause here */;

UPDATE table_1 SET card = NULL WHERE id in (select * from tmp_sub_table);    
UPDATE table_2 SET card = NULL WHERE id in (select * from tmp_sub_table);

我应该使用 本地临时表或 全局临时 table ?

最佳答案

全局临时表是持久数据结构。当我们 INSERT 将数据写入磁盘时,当我们 SELECT 时从磁盘读取数据。所以磁盘 I/O 相当多:运行相同查询两次所节省的成本必须大于所有这些写入和读取的成本。

需要注意的一件事是 GTT 是建立在临时表空间上的,因此您可能会与其他正在执行排序等长时间运行的进程发生争用。最好有一个单独的临时表空间,仅用于 GTT,但数量不多DBA 这样做。

另一种解决方案是使用集合将记录的子集存储在内存中并使用批量处理。

 declare
     l_ids sys.ocinumberlist;
     cursor l_cur is
         select id from sub_table WHERE /* complex clause here */
         order by id
         ;
begin
    open lcur;
    loop
        fetch lcur bulk collect into l_ids limit 5000;
        exit when l_ids.count() = 0;

        update table1 
        set card=null
        where id member of l_ids;

        update table2 
        set card=null
        where id member of l_ids;

    end loop;
end;

"updating many rows with one update statement ... works much faster than updating separately using Looping over cursor"



这是正常的建议。但这是一个批量操作:它一次更新五千行,所以它比逐行更快。批处理的大小由 BULK COLLECT ... LIMIT 控制。子句:您不希望将值设置得太高,因为集合在 session 内存中,但由于您只选择一列 - 和一个数字 - 也许您可以将其设置得更高。

与往常一样,调整是 的问题对标 .您是否确定运行此子查询两次是一项高成本操作?
select id from sub_table WHERE /* complex clause here */

如果它看起来太慢,您需要测试其他方法并查看它们是否更快。也许全局临时表比批量操作更快。通常内存访问比磁盘访问快,但您需要查看哪种方法最适合您。

关于oracle - Oracle中使用临时表优化SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45297325/

相关文章:

python - 带有python的智能过滤器

objective-c - 如何在从 NSUserDefaults 初始化时降低高圈复杂度

sql - 使用超过 2000 万条记录的 SSIS 的最佳增量加载方法

java - 识别何时使用 unsafe.allocateInstance() 创建对象

c# - 多语言网站性能

performance - Python GUI (tkinter.ttk) 应用程序速度慢

c++ - openMP过度同步

oracle - 从自定义子查询中选择列名称/别名列表

sql - 如果查询返回一行,如何选择一条记录,如果查询返回更多行,如何选择不记录?

oracle - 如何在SELECT FROM语句中使用表类型?