- ぬべたそ
- ベテラン
- 会議室デビュー日: 2003/12/18
- 投稿数: 72
|
投稿日時: 2007-06-11 12:11
>めだかさん、かずくんさん
ご返信ありがとうございます。
こちらからの書き込みが遅くなり申し訳ありません。
テスト用のテーブルを以下のように作成し、実験してみました。
TEST_DATAという核になるデータを扱うテーブルに、TEST_GYOMU_Aという業務を扱うテーブルが履歴型でぶら下がるイメージです。
書き込みが長くなりますが、お許し下さい。
DBはOracle10gです。
コード: |
|
CREATE TABLE TEST_DATA (
DATA_ID NUMBER(13) NOT NULL,
DATA_CONTENT VARCHAR2(255),
PRIMARY KEY(DATA_ID)
);
CREATE TABLE TEST_GYOMU_A (
DATA_ID NUMBER(13) NOT NULL,
REVISION NUMBER(3) NOT NULL,
REGIST_DATE DATE,
GYOMU_A_CONTENT VARCHAR2(255),
PRIMARY KEY(DATA_ID, REVISION),
FOREIGN KEY(DATA_ID) REFERENCES TEST_DATA
);
|
それぞれのテーブルに3万件のデータを作成し、以下のようなSQLを発行してみました。
コード: |
|
SELECT
TEST_DATA.DATA_ID,
TEST_DATA.DATA_CONTENT,
TEST_GYOMU_A.REVISION,
TEST_GYOMU_A.REGIST_DATE,
TEST_GYOMU_A.GYOMU_A_CONTENT
FROM TEST_DATA,TEST_GYOMU_A
WHERE
TEST_DATA.DATA_ID=TEST_GYOMU_A.DATA_ID AND
REVISION = (SELECT
MAX(B.REVISION)
FROM
TEST_GYOMU_A B
WHERE
B.DATA_ID=TEST_GYOMU_A.DATA_ID
)
|
Explainの結果は以下のようになりました。
コード: |
|
EXPLAIN実行結果>
SELECT STATEMENT Cost=1165
2.1 FILTER
3.1 SORT GROUP BY
4.1 HASH JOIN
5.1 TABLE ACCESS FULL TEST_DATA TABLE
5.2 HASH JOIN
6.1 INDEX FAST FULL SCAN SYS_C0036658 INDEX (UNIQUE)
6.2 TABLE ACCESS FULL TEST_GYOMU_A TABLE
|
次に業務Aと同様の構造のテーブル、業務Bを作成しました。
コード: |
|
CREATE TABLE TEST_GYOMU_B (
DATA_ID NUMBER(13) NOT NULL,
REVISION NUMBER(3) NOT NULL,
REGIST_DATE DATE,
GYOMU_B_CONTENT VARCHAR2(255),
PRIMARY KEY(DATA_ID, REVISION),
FOREIGN KEY(DATA_ID) REFERENCES TEST_DATA
);
|
そして、このテーブルも結合するように以下のようなSQLを作成しExplainを実行したところ、
3つのテーブルを結合するSQL
コード: |
|
SELECT
TEST_DATA.DATA_ID,
TEST_DATA.DATA_CONTENT,
TEST_GYOMU_A.REVISION,
TEST_GYOMU_A.REGIST_DATE,
TEST_GYOMU_A.GYOMU_A_CONTENT,
TEST_GYOMU_B.GYOMU_B_CONTENT
FROM TEST_DATA,TEST_GYOMU_A,TEST_GYOMU_B
WHERE
TEST_DATA.DATA_ID=TEST_GYOMU_A.DATA_ID AND
TEST_DATA.DATA_ID=TEST_GYOMU_B.DATA_ID AND
TEST_GYOMU_A.REVISION = (SELECT
MAX(B.REVISION)
FROM
TEST_GYOMU_A B
WHERE
B.DATA_ID=TEST_GYOMU_A.DATA_ID
)
AND
TEST_GYOMU_B.REVISION = (SELECT
MAX(C.REVISION)
FROM
TEST_GYOMU_B C
WHERE
C.DATA_ID=TEST_GYOMU_B.DATA_ID
)
|
Explain結果
コード: |
|
EXPLAIN実行結果>
SELECT STATEMENT Cost=56583
2.1 FILTER
3.1 SORT GROUP BY
4.1 FILTER
5.1 HASH JOIN
6.1 TABLE ACCESS FULL TEST_GYOMU_A TABLE
6.2 HASH JOIN
7.1 TABLE ACCESS FULL TEST_DATA TABLE
7.2 HASH JOIN
8.1 INDEX FAST FULL SCAN SYS_C0036662 INDEX (UNIQUE)
8.2 TABLE ACCESS FULL TEST_GYOMU_B TABLE
5.2 SORT AGGREGATE
6.1 FIRST ROW
7.1 INDEX RANGE SCAN (MIN/MAX) SYS_C0036658 INDEX (UNIQUE)
|
このように、COSTが大幅に増加してしまいました。
そこで、上記SQLに次の一行を追加してみました。
コード: |
|
TEST_GYOMU_A.DATA_ID=TEST_GYOMU_B.DATA_ID
|
結合条件を冗長にしてみました。
Explainの結果は
コード: |
|
EXPLAIN実行結果>
SELECT STATEMENT Cost=1548
2.1 FILTER
3.1 SORT GROUP BY
4.1 FILTER
5.1 HASH JOIN
6.1 HASH JOIN
7.1 TABLE ACCESS FULL TEST_GYOMU_B TABLE
7.2 HASH JOIN
8.1 TABLE ACCESS FULL TEST_DATA TABLE
8.2 TABLE ACCESS FULL TEST_GYOMU_A TABLE
6.2 INDEX FAST FULL SCAN SYS_C0036662 INDEX (UNIQUE)
5.2 SORT AGGREGATE
6.1 FIRST ROW
7.1 INDEX RANGE SCAN (MIN/MAX) SYS_C0036658 INDEX (UNIQUE)
|
のように、改善されたように見受けられます。
このような対策で問題無いでしょうか?
それとも他に見直さなければならない点などありました、ご教授下さい。
宜しくお願い致します。
|