Oracleはラベルを使用してバッチ更新データの6つの方式と速度比を行います。
1.情景展示
全部で22 wのデータがあります。 AテーブルのメインキーをBテーブルの指定フィールドに更新する必要がありますが、どのようにして更新が早く完了しますか?
2.ソリューション
宣言:
解決策は一つだけではなく、この文章は快速なマーキング法とコードの実現を紹介します。
二枚の表のIDとID_CARDフィールドはインデックスを作成しました。
方式一:暗黙的な遊覧標識を使用する(一回更新して1回提出する)
方式二:暗黙的な遊覧標識を使用する(1000回更新して1回提出する)(推奨使用)
方式三:明示的なラベル+バッチ更新(1000条1提出)
10000条1提出、実行時間:
方式四:明示的なラベル+配列(一回更新して提出する)(BULK COLLECTを使用する)
方式5: 明示的なラベル+配列(1000条に1回提出)(BULK COLLECTを使用)
方式六:おすすめの使用(BULK COLLECTとFOALLを使用)
Oracle 8から、oracleはPL/SQLのために2つの新しいデータ操作言語(DML)文を導入した。BULK COLLECTとFOALL。
この2つの文はPL/SQL内部で配列処理を行います。BULK COLLECTはデータの高速検索を提供しており、FOALLはINSERT、UDATE、DELETEの操作の性能を大幅に改善することができます。
Oracleデータベースはこれらの語句を使用して、PL/SQLとSQL文の実行エンジンの環境切替回数を大幅に減少させ、その性能を著しく向上させました。
リボン:
データ量が小さい時は方式二を使ってもいいです。データ量が大きい時は使い方六を勧めます。
インデックスを作成します。
以上はOracleがラベルを使ってバッチ更新を行う6つの方法と速度比の詳しい内容です。Oracleに関するラベルに関する資料は他の関連記事に注目してください。
全部で22 wのデータがあります。 AテーブルのメインキーをBテーブルの指定フィールドに更新する必要がありますが、どのようにして更新が早く完了しますか?
2.ソリューション
宣言:
解決策は一つだけではなく、この文章は快速なマーキング法とコードの実現を紹介します。
二枚の表のIDとID_CARDフィールドはインデックスを作成しました。
方式一:暗黙的な遊覧標識を使用する(一回更新して1回提出する)
--
BEGIN
FOR TEMP_CURSOR IN (SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ') LOOP
/* LOOP TEMP_CURSOR( TEMP_CURSOR) */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = TEMP_CURSOR.ID
WHERE ID_CARD = TEMP_CURSOR.ID_CARD;
COMMIT; --
END LOOP;
END;
実行時間:方式二:暗黙的な遊覧標識を使用する(1000回更新して1回提出する)(推奨使用)
/* */
DECLARE
V_COUNT NUMBER(10);
BEGIN
/* */
FOR TEMP_CURSOR IN (SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ') LOOP
/* */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = TEMP_CURSOR.ID
WHERE ID_CARD = TEMP_CURSOR.ID_CARD;
/* ,+1 */
V_COUNT := V_COUNT + 1;
/* 1000 1 */
IF V_COUNT >= 1000 THEN
COMMIT; --
V_COUNT := 0; --
END IF;
END LOOP;
COMMIT; -- , , ,
END;
実行時間:方式三:明示的なラベル+バッチ更新(1000条1提出)
/* */
DECLARE
V_COUNT NUMBER(10);
V_INDEX_ID PRIMARY_INDEX10.ID%TYPE;
V_ID_CARD PRIMARY_INDEX10.ID_CARD%TYPE;
CURSOR TEMP_CURSOR IS
SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ';
BEGIN
OPEN TEMP_CURSOR;
LOOP
/* */
FETCH TEMP_CURSOR
INTO V_INDEX_ID, V_ID_CARD;
/* */
EXIT WHEN TEMP_CURSOR%NOTFOUND;
/* */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = V_INDEX_ID
WHERE ID_CARD = V_ID_CARD;
/* ,+1 */
V_COUNT := V_COUNT + 1;
/* 1000 1 */
IF V_COUNT >= 1000 THEN
COMMIT; --
V_COUNT := 0; --
END IF;
END LOOP;
COMMIT; -- , , ,
CLOSE TEMP_CURSOR;
END;
実行時間:10000条1提出、実行時間:
方式四:明示的なラベル+配列(一回更新して提出する)(BULK COLLECTを使用する)
/* + ( ) */
DECLARE
/* : */
TYPE TYPE_INDEX_ID IS TABLE OF PRIMARY_INDEX10.ID%TYPE;
TYPE TYPE_ID_CARD IS TABLE OF PRIMARY_INDEX10.ID_CARD%TYPE;
/* */
V_INDEX_ID TYPE_INDEX_ID;
V_ID_CARD TYPE_ID_CARD;
/* */
CURSOR TEMP_CURSOR IS
SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ';
BEGIN
OPEN TEMP_CURSOR;
LOOP
/* 1000 , 1000 */
FETCH TEMP_CURSOR BULK COLLECT
INTO V_INDEX_ID, V_ID_CARD LIMIT 1000;
/* */
EXIT WHEN TEMP_CURSOR%NOTFOUND;
/* */
FOR I IN V_INDEX_ID.FIRST .. V_INDEX_ID.LAST LOOP
/* */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = V_INDEX_ID(I)
WHERE ID_CARD = V_ID_CARD(I);
COMMIT;
END LOOP;
END LOOP;
CLOSE TEMP_CURSOR;
END;
実行時間:方式5: 明示的なラベル+配列(1000条に1回提出)(BULK COLLECTを使用)
/* + (1000 ) */
DECLARE
/* : */
TYPE TYPE_INDEX_ID IS TABLE OF PRIMARY_INDEX10.ID%TYPE;
TYPE TYPE_ID_CARD IS TABLE OF PRIMARY_INDEX10.ID_CARD%TYPE;
/* */
V_INDEX_ID TYPE_INDEX_ID;
V_ID_CARD TYPE_ID_CARD;
/* */
CURSOR TEMP_CURSOR IS
SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ';
BEGIN
OPEN TEMP_CURSOR;
LOOP
/* 1000 */
FETCH TEMP_CURSOR BULK COLLECT
INTO V_INDEX_ID, V_ID_CARD LIMIT 1000;
/* */
EXIT WHEN TEMP_CURSOR%NOTFOUND;
/* */
FOR I IN V_INDEX_ID.FIRST .. V_INDEX_ID.LAST LOOP -- :FOR I IN 1 .. V_INDEX_ID.COUNT LOOP
/* */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = V_INDEX_ID(I)
WHERE ID_CARD = V_ID_CARD(I);
IF I >= V_INDEX_ID.LAST THEN
COMMIT; --
END IF;
END LOOP;
END LOOP;
CLOSE TEMP_CURSOR;
END;
実行時間:方式六:おすすめの使用(BULK COLLECTとFOALLを使用)
/* + (BULK COLLECT FORALL) */
DECLARE
/* : */
TYPE TYPE_INDEX_ID IS TABLE OF PRIMARY_INDEX10.ID%TYPE;
TYPE TYPE_ID_CARD IS TABLE OF PRIMARY_INDEX10.ID_CARD%TYPE;
/* */
V_INDEX_ID TYPE_INDEX_ID;
V_ID_CARD TYPE_ID_CARD;
/* */
CURSOR TEMP_CURSOR IS
SELECT T2.ID, T2.ID_CARD
FROM VIRTUAL_CARD10 T1, PRIMARY_INDEX10 T2
WHERE T1.ID_CARD = T2.ID_CARD
AND T1.REMARK = '** **** '
AND T2.REMARK = '** **** ';
BEGIN
OPEN TEMP_CURSOR;
LOOP
/* 1000 */
FETCH TEMP_CURSOR BULK COLLECT
INTO V_INDEX_ID, V_ID_CARD LIMIT 1000;
/* */
EXIT WHEN TEMP_CURSOR%NOTFOUND;
/* */
FORALL I IN 1 .. V_INDEX_ID.COUNT-- V_INDEX_ID.FIRST .. V_INDEX_ID.LAST
/* */
UPDATE VIRTUAL_CARD10
SET INDEX_ID = V_INDEX_ID(I)
WHERE ID_CARD = V_ID_CARD(I);
COMMIT; --
END LOOP;
CLOSE TEMP_CURSOR;
END;
実行時間:Oracle 8から、oracleはPL/SQLのために2つの新しいデータ操作言語(DML)文を導入した。BULK COLLECTとFOALL。
この2つの文はPL/SQL内部で配列処理を行います。BULK COLLECTはデータの高速検索を提供しており、FOALLはINSERT、UDATE、DELETEの操作の性能を大幅に改善することができます。
Oracleデータベースはこれらの語句を使用して、PL/SQLとSQL文の実行エンジンの環境切替回数を大幅に減少させ、その性能を著しく向上させました。
リボン:
データ量が小さい時は方式二を使ってもいいです。データ量が大きい時は使い方六を勧めます。
インデックスを作成します。
以上はOracleがラベルを使ってバッチ更新を行う6つの方法と速度比の詳しい内容です。Oracleに関するラベルに関する資料は他の関連記事に注目してください。