在oracle 8i中插入大行

问题描述 投票:0回答:1

我们需要使用 Oracle 8i 在表中插入大约 250,000-500,000 行的大行。有 3 列,每列仅包含 3 个字符。我编写了一个简单的 shell 脚本,因此我们有一个本地 Oracle 19c DB,它在大约 1 到 2 分钟内完成插入。(使用 Sql*Loader 不是我们的选择)

现在的问题是我需要插入的实际数据库是 Oracle 8i。我正在使用完全相同的脚本。即使插入 10000 条记录也需要花费大量时间。我发现以目前的速度,同样的过程将需要大约 8 个小时。出了什么问题?我该如何优化它。了解 Oracle 的版本是否负责或其他原因会很有帮助。我尝试过使用差异大小(如 200,500,1000 等)的批量插入,但没有帮助。批量插入在 Oracle 8i 中没有帮助吗?事实上,批量插入使得 19c 的速度大大加快。

编辑:我正在添加我正在使用的 shell 脚本,在 19c 中插入 1000 条记录只需半秒,但相同的脚本需要几分钟,而实际记录则需要几个小时。所以我从 db1 获取记录并将其插入到 db2。 TEMP_SQL_FILE 的目的也是收集 1000 个插入命令作为文件中的字符串。 BATCH_SIZE=50 帮助我收集 50 个这样的插入字符串并将其放入文件中。所以最终,1000

INSERT INTO TABLE2 (USERID, SALARY, ZIP) VALUES ('$USERID', '$SALARY', '$ZIPCODE'); 
将收集在临时文件中,然后通过 sql plus 插入。

#!/bin/ksh

# DB1 (source database) details (**19c**)
DB1_USER="user1"
DB1_PASSWORD="pwd1"
DB1_DB=db1.abc.com

# DB2 (destination database) connection details (**8i**)
DB2_USER="user2"
DB2_PASSWORD="pwd2"
DB2_DB=db2.xyz.com

# Temporary file to hold SQL commands
TEMP_SQL_FILE="batch_inserts.sql"
BATCH_SIZE=50  # Number of records to accumulate before writing to file
COMMIT_THRESHOLD=1000  # Number of records after which to commit
counter=0  # To keep track of total records written
batch_counter=0  # To track batch size
sql_batch=""

# SQL Query to fetch data from DB1 table1 table
SQL_QUERY="SELECT userid || '|' || salary || '|' || zip FROM table1;"

# Fetch data from DB1 and insert into DB2
sqlplus -s "$DB1_USER/$DB1_PASSWORD@$DB1_DB" <<EOF | while IFS='|' read -r USERID SALARY ZIPCODE
SET HEADING OFF
SET FEEDBACK OFF
SET PAGESIZE 0
SET LINESIZE 1000
$SQL_QUERY
EXIT;
EOF

do
    # Accumulate SQL insert statements in the batch variable
    sql_batch+="INSERT INTO TABLE2 (USERID, SALARY, ZIP) VALUES ('$USERID', '$SALARY', '$ZIPCODE');\n"
    ((batch_counter++))
    ((counter++))

    # Check if we reached the batch size, then write to file
    if [ "$batch_counter" -ge "$BATCH_SIZE" ]; then
        echo -e "$sql_batch" >> "$TEMP_SQL_FILE"
        sql_batch=""  # Clear the batch variable
        batch_counter=0  # Reset the batch counter
    fi

    # Check if we reached the commit threshold
    if [ "$counter" -ge "$COMMIT_THRESHOLD" ]; then
        # Execute the SQL batch
        sqlplus -s "$DB2_USER/$DB2_PASSWORD@$DB2_DB" <<EOF
        @$TEMP_SQL_FILE
        COMMIT;
        EXIT;
EOF
        # Clear the temporary file after commit
        > "$TEMP_SQL_FILE"
        counter=0  # Reset the counter after commit
    fi
done

# Final commit for any remaining records
if [ -n "$sql_batch" ]; then
    echo -e "$sql_batch" >> "$TEMP_SQL_FILE"
fi

if [ -s "$TEMP_SQL_FILE" ]; then
    sqlplus -s "$DB2_USER/$DB2_PASSWORD@$DB2_DB" <<EOF
    @$TEMP_SQL_FILE
    COMMIT;
    EXIT;
EOF
fi

# Clean up
rm "$TEMP_SQL_FILE"
sql oracle oracle19c oracle8i
1个回答
0
投票

尝试以下方法(步骤在一个会话中执行):

第1步:

ALTER SESSION SET skip_unusable_indexes = true;

第 2 步: 禁用索引

ALTER INDEX index_name UNUSABLE;

第 3 步: 导入

第4步:重建索引

ALTER INDEX index_name REBUILD [ONLINE];
© www.soinside.com 2019 - 2024. All rights reserved.