OracleでのSQL高速化
かなり前なりますが作った処理が遅く、「SQLだけでも見直せ!!」ということで調べていた内容です。
SQLを高速化するチューニングは難しいですが、以下のことを知っているだけでも少しはましなので、書いておきます。
キーワードは大文字
SQLのキーワードはすべて大文字で書く。(キャッシュを使う確率をあげる)
○ SELECT col1 FROM table1 WHERE col2 = '100' ; × select col1 From test1 wHere col2 = '100' ;
これは高速化にも寄与しますし、コーディング上キーワードを大文字で統一しておくことで、ソース上での検索キーワードなどにも指定でき、デバッグにも役立ちます。
(大文字だけの「SELECT」を探せば実際に「SELECT」文を発行 している箇所がgrepだけで検索できます。)
バインド変数利用
可能であればバインド変数を利用する。
SELECT col1 FROM test1 WHERE col2 = :col1_data ;
これもSQLのキャッシュへのHIT率を上げます。
「:col_data」の内容が変化してもSQLがキャッシュに残っていればSQLの再コンパイルが実行されないので、その分、応答時間が短くなります。
SELECT * は不可
SELECT * は使用不可。
○ SELECT col1, col2 FROM test1 ; × SELECT * FROM test1 ;
これもSQLのキャッシュへのHIT率を上げるようです。
また、無駄なカラムを取得する処理が省かれるようなので必ず指定しましょう。
SELECT COUNT(*)は使用不可
SELECT COUNT(*)は使用しない。
○ SELECT COUNT( col1 ) FROM test1 ; × SELECT COUNT(*) FROM test1 ;
但し、col1に「NULL」データが含まれるかどうかの確認は必要です。
ANDよりBETWEEN
ANDよりBETWEENの使用を検討する。
○ SELECT col1 FROM table1 WHERE col2 BETWEEN 0 AND 3000 ; × SELECT col1 FROM table1 WHERE col2 >= 0 AND col2 <= 3000;
HAVINGよりWHERE
HAVINGよりWHEREの使用を検討する。
○ SELECT col1, SUM( col2 ) FROM test1 WHERE col3 = 'D02' GROUP BY col2 ; × SELECT col1, SUM( col2 ) FROM test1 GROUP BY col2 HAVING col2 = 'D02' ;
テーブルの別名
テーブルに別名を付ける。
○ SELECT a.col1, a.col2 FROM test1 a; × SELECT a.col1, a.col2 FROM test1 ;
ROWIDの利用
可能であるならばROWIDの利用を検討する。
SELECT col1, col2, rowid FROM table1 UPDATE table1 SET col1 = 250 WHERE rowid = 'zzaF+OAAIabcBMMABL' ;
複雑なWHERE句を書いているのであれば、ROWIDを使用することにより、直接レコードを特定できるので処理が速くなります。
列の演算不可
列を演算(関数を使用)しない
○ SELECT * FROM tab1 WHERE c1 < 1000 ; × SELECT * FROM tab1 WHERE c1 / 10 < 10000 ;
これをやってしまうと、せっかく設定した「index」が利用されず処理が遅くなります。
これは特に注意が必要です。