AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 29021
Accepted
a1ex07
a1ex07
Asked: 2012-11-21 16:27:24 +0800 CST2012-11-21 16:27:24 +0800 CST 2012-11-21 16:27:24 +0800 CST

Oracle 10g 使用 sql 集合

  • 772

我有一个收集对象的存储过程。( TABLE OF MyCustomType)。在过程中,我试图将此参数与真实表连接起来。

例如,像

create or replace TYPE MYTYPE AS OBJECT (....);  
CREATE OR REPLACE TYPE LIST_OF_MYTYPE AS TABLE OF MYTYPE;

CREATE PROCEDURE FOO(my_table LIST_OF_MYTYPE ,....) AS
  CURSOR cur_read_data IS 
  SELECT a.col1, b.col2, b.col3
  FROM 
  TABLE(FOO.my_table) a
  INNER JOIN existing_table b ON (b.existing_table_id = a.existing_table_id)
  --b.existing_table_id - primary key supported by unique index
  ORDER BY a.existing_table_id
  ;

BEGIN
     FOR record_info in cur_read_data 
     LOOP 
        ......
     END LOOP;
END;

它有效,但我有一个性能问题。传递给过程的集合参数没有很多元素;即使它只有一个元素,执行计划也会涉及对existing_table.

在 1 个元素的情况下,更改INNER JOIN existing_table b ON (b.existing_table_id = a.existing_table_id)为INNER JOIN existing_table b ON (b.existing_table_id =FOO.my_table(1).existing_table_id )会产生巨大的差异 - 查询使用“INDEX UNIQUE SCAN”,正如我在初始查询中所期望的那样。我什至尝试过没有结果的查询提示(有序,领先)......

即使我的应用程序中集合中的元素数量在 1 到 5 之间,并且可以编写一个过程的 5 个不同版本,我想知道是否可以使其按预期工作。

为了测试,我也做了

CURSOR cur_read_data IS 
  SELECT a.col1, b.col2, b.col3
  FROM 
   ( 
     SELECT 1 as existing_table_id, 'test 1' as col1 FROM DUAL
      UNION
     SELECT 2 as existing_table_id, 'test 2' as col1 FROM DUAL
      UNION
     SELECT 3 as existing_table_id, 'test 3' as col1 FROM DUAL
   )
  a
  INNER JOIN existing_table b ON (b.existing_table_id = a.existing_table_id)
  --b.existing_table_id - primary key supported by unique index
  ORDER BY a.existing_table_id

这样它也可以按预期工作,INDEX_UNIQUE_SCAN,而不是全扫描......

感谢您的回答。

更新 相当令人惊讶,但将其重写为

CURSOR cur_read_data IS 
  WITH CTE1 AS (SELECT * FROM TABLE(FOO.my_table))
  SELECT a.col1, b.col2, b.col3
  FROM 
  CTE1 a
  INNER JOIN existing_table b ON (b.existing_table_id = a.existing_table_id
  AND b.existing_table_id IN (SELECT existing_table_id FROM CTE1))      
  ORDER BY a.existing_table_id

成本降低了大约 30 倍(1200 原始版本与 38 版本WITH)这是可以接受的,但我仍然不知道为什么这有帮助......

另一个更新

分析V$SQLSTATS表明,对于游标的第一个版本,它不惜一切代价避免 DISK READS (0),DIRECT WRITES 也是 0;使用WITH以某种方式更改执行计划导致 CPU TIME 的巨大改进超过增加的 DISK READS (1)...

performance optimization
  • 1 1 个回答
  • 2259 Views

1 个回答

  • Voted
  1. Best Answer
    Justin Cave
    2012-11-22T08:58:39+08:002012-11-22T08:58:39+08:00

    在 SQL 中使用集合的问题之一是优化器无法猜测集合有多少元素。它默认假设集合有几千个元素(我想说 4k 元素,但我不会下注)。如果这比实际集合中的元素多大约 1,000 倍,那肯定会导致优化器对查询计划做出错误的选择。

    缓解该问题的最佳方法是使用CARDINALITY提示。

    SELECT /*+ cardinality(a 4) */ a.col1, b.col2, b.col3
      FROM 
      TABLE(FOO.my_table) a
      INNER JOIN existing_table b ON (b.existing_table_id = a.existing_table_id)
      --b.existing_table_id - primary key supported by unique index
      ORDER BY a.existing_table_id
    

    告诉优化器假设别名为的集合a只有 4 个元素,这应该导致它选择更合适的查询计划。

    • 1

相关问题

  • 使用存储过程处理数据与在检索后将其输入函数相比是否有性能提升?

  • 您如何针对繁重的 InnoDB 工作负载调整 MySQL?

  • 如何确定是否需要或需要索引

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve