• 検索結果がありません。

DB の件数を考慮した記述

ドキュメント内 HiRDB SQLコーディングガイドライン (ページ 58-69)

( BROADCAST )

6. DB の件数を考慮した記述

57

DBアクセス性能は、検索結果件数および検索中(SQL実行中)にアクセス

するデータ件数に大きく依存します。この場合の

SQL

コーディングについて示 します。

6-1 表の件数の取得

表の件数を求めるときは、以下を指定してください。

 COUNT

(*)を使う。このとき可能な限り

WITHOUT LOCK NOWAIT

を指定する。

条件式にはインデクスの定義された列を指定する。

例を図 6-1-1に示します。

条件式に指定した列がインデクスの第一構成列でない場合、性能が悪くなることがありま す。

Point

表の件数を求めるとき、

COUNT

(*)を使用すること

SELECT COUNT(*) FROM ZAIKO

WHERE ZSURYO > 10 WITHOUT LOCK NOWAIT ;

件数の取得には

COUNT

(*)を使用する。

ZSURYO

にインデクスを定義する。

図 6-1-1 件数の取得の

SQL

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-2 データの存在有無の取得

59

データの存在チェックを行うときの留意事項を以下に記載します。

 LIMIT 1

を指定して、

1

件見つけたら処理を打ち切るようにする。

可能な限り

WITHOUT LOCK NOWAIT

を指定する。

条件式と選択式にはインデクスの定義された列を指定する。

 ORDER BY

は作業表を作成することがあるため、指定しない。

例を図 6-2-1に示します。

Point

データの存在チェックには

LIMIT

を使用すること

SELECT ZA.ZSURYO FROM ZAIKO ZA

WHERE ZA.ZSURYO = 0 LIMIT 1

WITHOUT LOCK NOWAIT ;

ZSURYO にインデクスを定義する。

図 6-2-1 存在チェックの

SQL

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-3 NOT (!=) の使用上の注意

60

NOT

!=

)を使用した条件に対して、

HiRDB

は、あまり絞り込めないと判断し結合方法、

結合順序を決定します。取り得る値が1か0だけのフラグなど2値しか持たない列は、

条件に指定してもあまり絞り込めないので、

NOT

!=

)を使用して条件を指定することで、

HiRDB

は、絞り込めないことを認識できます。3値以上持つがあまり絞り込めない場合は、

NOT IN

を用いても良いです。例を図 6-3-1に示します。

Point

絞り込めないとわかっている条件は

NOT

!=

)を指定する

~ FROM JUTYU JU,ZAIKO ZA WHERE JU.DNO = ZA.DNO AND JU.FLAG != 1 AND ZA.ZSURYO = 20

×

~ FROM JUTYU JU,ZAIKO ZA WHERE JU.DNO = ZA.DNO AND JU.FLAG = 0

AND ZA.ZSURYO = 20

JU.FLAGは、1か0であり、かつ ZA.ZSURYO=20が絞り込める場合

図 6-3-1 結合を伴う

SQL

での

NOT

使用例

JU.FLAG != 1とすることで、

ZA.ZSURYO = 20のインデクスを

確実に使用し、

ZA

から

JU

へのネスト ループジョインにて高速に処理する。

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-4 集合演算の使用上の注意(1)

61

UNION/UNION ALL

などの集合演算を使用したとき、集合演算で区切られた問合せ指

定(

SELECT

文)は、別々に表アクセスします。また、集合演算を使用すると、作業表を作

成することが多いです(

UNION ALL

のみの集合演算であれば集合演算のための作業表 は作成しない)。そのため、集合演算を用いない

SQL

文にすると処理性能が向上すること が多いです。

図 6-4-1に、単純な場合の例を示します。

Point

各問合せ指定の述語に指定する値だけが異なるような場合は、集合演算を

使用しないようにする

SELECT SNAME FROM ZAIKO

WHERE ZSURYO IN (10, 20) ;

×

SELECT SNAME FROM ZAIKO

WHERE ZSURYO = 10 UNION

SELECT SNAME FROM ZAIKO

WHERE ZSURYO = 20 ;

=条件の値だけが異なる場合は、

UNION

等の集合演算を使用しない。

図 6-4-1 集合演算を使用しないSQL文の例

IN

述語を使用することにより集合演 算を使用しない。

DB

の件数を考慮した記述

6-4 -1 集合演算の使用上の注意(2)

結合条件を

OR

論理演算すると、

HiRDB

は、直積で処理します。直積では、全データの 突合せ処理を伴うため、集合演算に変形し、

OR

論理演算を不要とすることで直積処理が 無くなり処理性能が向上することが多いです。

例を図 6-4-2、6-4-3に示します。

Point

結合を伴う

SQL

で、結合条件を

OR

論理演算する必要がある場合は、集合演算 を使用する

SELECT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE JU.DNO = ZA.DNO UNION ALL

SELECT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE JU.ZNO = ZA.ZNO AND JU.DNO != ZA.DNO ;

×

SELECT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE (JU.DNO = ZA.DNO OR JU.ZNO = ZA.ZNO) ;

DISTINCT無し。結合条件をOR論理

演算している。

図 6-4-2 直積を回避するためにUNION ALLを利用するSQL文の例

UNION ALL

を利用し、結合条件

OR

をなくす。

UNION ALL

で処理できるように 工夫する。

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-4 -2 集合演算の使用上の注意(3)

63

SELECT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE JU.TCODE = 'A01' AND JU.DNO = ZA.DNO

UNION

SELECT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE JU.TCODE = 'A01'

AND JU.SURYO = ZA.ZSURYO ;

×

SELECT DISTINCT ZA.NAME

FROM JUTYU JU, ZAIKO ZA WHERE JU.TCODE = 'A01' AND (JU.DNO = ZA.DNO

OR JU.SURYO = ZA.ZSURYO) ;

DISTINCT指定有り。

結合条件を

OR

論理演算している。

図 6-4-3 直積を回避するために

UNION

を利用する

SQL

文の例

UNIONを利用し、結合条件のOR

をなくす。

UNION

では重複を排除するため、

DISTINCTの指定が不要。

DB

の件数を考慮した記述

6-5 DISTINCT の使用上の注意

DISTINCT

は重複排除のために作業表作成とソートを行います。そのオーバヘッドが

あるので、必要のない

DISTINCT

は使用しないでください。重複排除が必要な場合でも、

選択式が列指定のみで、かつ値の重複が多い場合は、GROUP BYを用いてください。例 を図 6-5-1に示します。

GROUP BY

を用いた場合、以下の向上が図れます。

インデクスが定義されていれば、インデクスを利用して、重複排除を効率よく行える。

インデクスを利用できなくても、グループ分け高速化機能

SQL

最適化オプション)

が適用できれば、処理性能が向上することが多い。

Point DISTINCT

は、確実に重複があり、重複を排除する必要がある場合以外

使用しない

SELECT SNAME FROM ZAIKO

GROUP BY SNAME ;

SELECT DISTINCT SNAME FROM ZAIKO ;

不要なDISTINCTは使用しない。

図 6-5-1 重複排除を効率よく行うSQL文の例

選択式が列のみで、重複が多い場 合の重複排除は、GROUP BYを用 いる。

<補足事項>

GROUP BYを使用する場合、重複排除した結果の行数が1024(クライアント環境定義のPDAGGRデフォルト値)

を超えるならば、PDAGGRに1024より大きい値を指定すると処理性能が向上する場合があります。

* SQLのGROUP BY句を指定してグループ分け処理をする場合、ソートしてからグループ分けをしています。これにハッシングを組み合わせて グループ分けすることで高速なグループ分け処理が実現できます。

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-6 ビュー表の使用上の注意(1)

65

ビュー表定義に、

DISTINCT

GROUP BY

、結合表を指定すると、内部導出表を作成す ることが多くなります(内部導出表の作成条件は、マニュアル「

SQL

リファレンス」を参照)。

ビュー表定義で内部導出表を作成した場合、以下のような点で性能が悪くなります。

内部導出表は、ビュー定義時の導出問合せ式の結果で作成する作業表であるため、

作業表への

I/O

が発生する。

内部導出表を作成すると、ビュー表検索時に指定した探索条件は、内部導出表の作

成後に評価するため、内部導出表作成時の処理件数が多くなり性能が悪くなる。

これらは、ビュー表だけでなく、WITH句を含めた名前つき導出表すべてに該当します。

例を図 6-6-1、6-6-2に示します。

Point

ビュー表定義で

DISTINCT

指定、

GROUP BY

指定は注意が必要

ビュー表定義で結合表(LEFT OUTER JOIN/INNER JOIN)指定は注意が必要

DB

の件数を考慮した記述

6-6 -1 ビュー表の使用上の注意(2)

CREATE VIEW V1(DNO, TCODE) AS SELECT DNO, TCODE

FROM JUTYU ;

SELECT DISTINCT ZA.SNAME FROM V1 V, ZAIKO ZA

WHERE V.DNO = ZA.DNO AND V.TCODE = 'A' ;

×

CREATE VIEW V1(DNO,TCODE)

AS SELECT DISTINCT DNO,TCODE FROM JUTYU ;

SELECT ZA.SNAME

FROM V1 V, ZAIKO ZA WHERE V.DNO = ZA.DNO AND V.TCODE = 'A' ;

DISTINCT

を指定すると内部導出表 となる。

図 6-6-1 内部導出表とならないビュー表の例 その1

この条件はDISTINCT処理後に評価 する。

重複排除が必要な場合は

VIEW

外に記述する。

内部導出表とならないため、この条 件はDISTINCT処理前に評価できる。

DB

の件数を考慮した記述

© Hitachi, Ltd. 2013 , 2015. All rights reserved.

6-6 -2 ビュー表の使用上の注意(3)

67

CREATE VIEW V1(SCODE,TCODE) AS SELECT ZA.SCODE, JU.TCODE FROM JUTYU JU, ZAIKO ZA WHERE JU.DNO= ZA.DNO ; SELECT ZA2.SNAME

FROM V1 V, ZAIKO2 ZA2

WHERE V.SCODE = ZA2.SCODE AND V.TCODE = 'A' ;

×

CREATE VIEW V1(SCODE,TCODE) AS SELECT ZA.SCODE, JU.TCODE

FROM JUTYU JU INNER JOIN ZAIKO ZA ON JU.DNO= ZA.DNO ;

SELECT ZA2.SNAME

FROM V1 V, ZAIKO2 ZA2

WHERE V.SCODE = ZA2.SCODE AND V.TCODE = 'A' ;

INNER JOIN

を指定すると内部導 出表となる場合がある。

ビュー定義時のINNER JOIN処理 後に評価する。

ビュー定義では、INNER JOINを 使用しない。

内部導出表とならないため、ビュー 定義時の結合処理前に評価できる。

図 6-6-2 内部導出表とならないビュー表の例 その2

DB

の件数を考慮した記述

ドキュメント内 HiRDB SQLコーディングガイドライン (ページ 58-69)