我正在转换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中这种令人难以置信的缓慢性能的想法吗?
答案 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
上没有支持索引,但您要求不要专注于此。