pl / sql比光标慢

时间:2017-11-04 11:14:47

标签: sql oracle

我正在转换SQL Server系统以在Oracle(11g)上运行。系统已全部设置,数据加载等。数据量非常大(表中的160m记录等)。该服务器是HP DL380,具有1tb raid 1 + 0和96gb内存。

在测试中,我发现莫名其妙,因为使用3-4个表的SQL插入语句需要90分钟才能运行,而使用游标的相同逻辑大约需要3分钟!

对于游标大约需要8分钟,对SQL Server大约需要2-3分钟(这是我期望的)。

换句话说,Oracle SQL比游标慢30-50倍。它给我的印象是Oracle系统在OLTP(单个记录插入)上非常快,但在SQL中操作较大的表时确实很慢。

我确信这不是通常的情况,所以我问,是否有任何Oracle参数'那需要调整吗?

以下是使用的SQL示例:

INSERT INTO TMP_TXN ......
SELECT .......
  FROM TXN (160m rows), CUSTOMERS (1m rows), PRODUCTS (1k rows)
 WHERE TXN.TXN_DATE = p_date 
   AND TXN.TXN_AMOUNT > 0 
   AND TXN.PRODUCT_ID = PRODUCTS.PRODUCT_ID 
   AND PRODUCTS.PRODTYPE_ID IN ('1', '12', '13');
   AND TXN.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID 
   AND CUSTOMERS.CUSTOMER_STATUS LIKE 'A%' 

FOR item IN (SELECT .....
              FROM TXN (160m rows), CUSTOMERS (1m rows), PRODUCTS (1k rows)
              WHERE TXN.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID
                AND CUSTOMERS.CUSTOMER_STATUS LIKE 'A%'
                AND TXN.PRODUCT_ID = PRODUCTS.PRODUCT_ID
                AND PRODUCTS.PRODTYPE_ID IN ('1', '12', '13')
                AND TXN.TXN_DATE = p_date
                AND TXN.TXN_AMOUNT > 0
              ORDER BY CUSTOMER_ID);
  LOOP         
     IF item.customer_id <> customer_id_old THEN
     etc.

索引(在TXN上)用于CUSTOMER_ID和TXN_DATE。 TMP_TXN上的索引适用于CUSTOMER_ID(以及此脚本不需要的其他一些索引)。

请不要对此示例SQL感到困惑。它是几百个之一,每个单一运行缓慢,但使用游标时,脚本运行速度提高10-50倍。运行SQL时,我查看资源监视器,看到几乎没有触及Data表空间(1mb / sec),而UNDO / REDO表空间是3-50mb / sec。 REDO日志文件大小调整为10gb,因为它们之前每1-2秒切换一次!

由于这是完全错误的,我的猜测是我错过了一些Oracle安装问题。对于Oracle SQL中这种令人难以置信的缓慢性能的想法吗?

1 个答案:

答案 0 :(得分:0)

如果您正在进行一些不需要Oracle实时备份的大批量操作,您可以考虑使用Direct Load Insert,它将跳过编写REDO。

INSERT /*+ append nologging */ INTO TMP_TXN ...
SELECT ...

在“高水位”后面附加问题,这是表格在表空间中的位置的当前末尾,而不是搜索足够大的空块以插入新行。根据您的数据库设置,必须使Direct Load工作more info here。在表的DDL中定义它并不是强制性的,因为您可能不会在每个操作中都需要它。

根据p_date参数判断,您在PL / SQL过程中使用了两者吗?请注意在plsql引擎和sql引擎has an impact on the performance之间切换。在处理它们之前,FOR语句将获取大约100行,这会带来一些好处,但插入仍然是逐行的。

给定的示例似乎在每个客户的n个插入和仅1个插入之间有所不同,并且CUSTOMERS上没有支持索引,但您要求不要专注于此。