sql - 从 PL/SQL 插入到临时表 GTT 非常慢

标签 sql performance oracle sql-tuning

我有一个从 SQL 执行时表现出色的查询。

它是表和查询之间的连接。这两个表都有接近 400 万条记录。 我试图提供提示的文档表上有位图索引。当我从蟾蜍那里看到时,解释计划确实表明它们正在帮助加入。

我提供了 2 个其他提示,看看它们是否有帮助。一种用于直接路径 APPEND,另一种用于利用 pda 上现有的 BTree 索引。

当此查询针对 SQL 中的替换变量运行时,结果是即时的,但过程中的相同查询需要 8 秒或更长时间。

除了 DBA 尚未提交的程序计划外,您认为我可能有什么明显的遗漏?提前致谢。

 
     INSERT                                                           /*+ APPEND */
          INTO  tmp_search_gross_docs (document_id,
                                       last_name,
                                       first_name,
                                       person_doc_association_id,
                                       association_date)
       SELECT                 /*+INDEX(pda IDX_DOC_PDOC_DOCID ) USE_NL(pda doc) */
             pda.document_id,
              last_name,
              first_name,
              person_doc_association_id,
              association_date
         FROM   pda,
              (SELECT /*+INDEX_COMBINE(attr IDX_BMP_SEARCH_FN,IDX_BMP_SEARCH_LN)*/
                      document_id, last_name, first_name
                 FROM doc attr
                WHERE first_name LIKE l_first_name OR last_name LIKE l_last_name) doc
        WHERE pda.document_id = doc.document_id;
                         ) doc
                 WHERE pda.document_id = doc.document_id;

  

解释计划(来自 Toad 的绑定(bind)变量)

INSERT STATEMENT ALL_ROWSCost:1,086,010 字节:15,309,420 基数:364,510
11 加载为选择 TMP_SEARCH_GROSS_DOCS
10 TABLE ACCESS BY INDEX ROWID TABLE PDA 成本:3 字节:20 基数:1
9 个嵌套循环成本:1,086,010 字节:15,309,420 基数:364,510
7 通过索引 ROWID 表 ATTR 访问表 成本:23,893 字节:8,019,220 基数:364,510
6 位图转换为行
5 位图或
2 位图合并
1 位图索引范围扫描索引(位图)IDX_BMP_SEARCH_FN 4 位图合并
3 位图索引范围扫描索引(位图)IDX_BMP_SEARCH_LN 8 INDEX RANGE SCAN INDEX IDX_PDA_EXP_DOC 成本:2 基数:1

基数 364,510 似乎不对,因为该表包含 3738562 行,而对于 WHERE 中列的替换值,计数仅为 8892。

但同样,这个计划至少告诉我正在使用正确的索引,并且在 toad 编辑器中运行得非常快。

来自 PL/SQL 的实际计划仍然不可用。

不确定这是否会增加一些有值(value)的信息。但是思想还是会编辑的。谢谢

最佳答案

首先,我不认为使用 append 插入 GTT 有任何逻辑。我可能是错的,但据我所知,附加绕过缓冲区缓存并直接写入文件,它写入高水位线以上并且在提交之前不允许查询。 GTT 不在常规数据文件上 - 它在临时文件上,并且在提交时被截断(默认设置)。

我认为,如果您不需要在查询后操作数据,请考虑向应用程序返回一个引用游标。它基本上是同一件事 - 许多 DAL 层都是以这种方式实现的。

如果您仍然想要 GTT,我会检查我的临时文件分配,包括大小和实际磁盘 - 您的 DBA 可能已将它们放在不同的设备上。

关于sql - 从 PL/SQL 插入到临时表 GTT 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15978395/

相关文章:

c# - 将数据写入数据库不起作用

mysql - 如何使索引良好的 MySQL 表有效地连接

java - 如何在 IBatis 2 中使用 SQL Like 运算符?

java - Oracle Solaris Studio 性能分析器 12.3 的使用

mysql - 仅考虑 COUNT 个特定 ID

sql - 查询适用于 MySQL 而不是 Oracle

mysql - 如何从mysql表中获取最后一个列名?

performance - 如果我们应该在 Haskell 中避免使用foldl,那么我们是否也应该避免基于它的所有助手呢?

performance - Chrome Lighthouse 用于移动测试是否已损坏?

sql - 更新查询在 SQL Server 中运行,但不在 Oracle 中运行