SQLの効率化 [2009年07月02日(木)]
テーブルAがあり、プライマリーキーではない、任意の文字列フィールドに対して、
キーワード検索の機能を改善をすることになりました。
全角/半角、大文字/小文字の統一なしで登録されています。
例)MS MS ms エムエス エムエス など
で、検索する側が、MSといれて MSがヒットしないといって苦情が出ています。
しかも、件数が多いと、検索に数分かかります。
しょうがないので検索用のテーブルA'を作成し、
A'には、PKeyと、すべて大文字/全角化(カタカナは、ひらがなに)したカラム KeyWordカラムだけ登録し、Indexの代わりにして効率化をはかりました。
select A.* from A,
(select A'.PKey from A' where KeyWord like %大文字/全角化した検索キーワード%)temp
where A.Pkey =temp.Pkey
として、副問合せのSQLを作りました。
実行計画の確認をすると、Hash 結合にはなっていますが、コストが異常に高い
で、よく見てみると テーブルAが Full Table アクセスになっている。
PKeyが効いていません。
で、インデックスを使えとHint指定しても変わらず、
副問合せの中を 試しに=にして評価すると、Pkeyでスキャンされます。
どうも、Oracle10iでは、副問合せの中でLikeを使うと、インデックスが無視されるようです。
このままでは、パフォーマンスが上がらないので、頭を切り替え、
副問合せをwhere句から、select句に変更して、LikeをメインのSQL内に変更しました。
select A'.Pkey ,(select A.* from A where A.Pkry=A'.Pkey)
from A' where KeyWord like %大文字/全角化した検索キーワード%
とすると、今度はPkeyでIndexスキャンされるので、
コストが、2000から500まで落ちました。
で、実際に画面を動かしてみると、Hit件数は1万のとき、画面が表示されるまで、3分以上かかります、
パフォーマンスが全然改善していません。
既存の画面を調べてみると、htmlフォーマットで、検索結果をダウンロード幼のファイルとして出力していました。
嫌な予感がしたので、ファイル出力をころしてみると、
秒のオーダーまでパフォーマンスが改善しました。
ファイルIOにボトルネックがあるのは間違いないようです。
しかし、セイゼイ600K 1万行程度のhtmlファイルの出力にしては時間がかかりすぎています。
既存画面の、ファイル出力は自作のProcedureでした(画面はPL/SQL)
嫌な予感がしたので、Procedureを確認すると、
1行出力するごとに、ファイルをOpen/Closeしています。
アホかー
1万回のファイルOpen/Closeって、どんな負荷テストやねん。
ファイルOpen/Closeを1回だけにしたら、応答時間は秒のオーダーになりました。
ちゃんちゃん
キーワード検索の機能を改善をすることになりました。
全角/半角、大文字/小文字の統一なしで登録されています。
例)MS MS ms エムエス エムエス など
で、検索する側が、MSといれて MSがヒットしないといって苦情が出ています。
しかも、件数が多いと、検索に数分かかります。
しょうがないので検索用のテーブルA'を作成し、
A'には、PKeyと、すべて大文字/全角化(カタカナは、ひらがなに)したカラム KeyWordカラムだけ登録し、Indexの代わりにして効率化をはかりました。
select A.* from A,
(select A'.PKey from A' where KeyWord like %大文字/全角化した検索キーワード%)temp
where A.Pkey =temp.Pkey
として、副問合せのSQLを作りました。
実行計画の確認をすると、Hash 結合にはなっていますが、コストが異常に高い
で、よく見てみると テーブルAが Full Table アクセスになっている。
PKeyが効いていません。
で、インデックスを使えとHint指定しても変わらず、
副問合せの中を 試しに=にして評価すると、Pkeyでスキャンされます。
どうも、Oracle10iでは、副問合せの中でLikeを使うと、インデックスが無視されるようです。
このままでは、パフォーマンスが上がらないので、頭を切り替え、
副問合せをwhere句から、select句に変更して、LikeをメインのSQL内に変更しました。
select A'.Pkey ,(select A.* from A where A.Pkry=A'.Pkey)
from A' where KeyWord like %大文字/全角化した検索キーワード%
とすると、今度はPkeyでIndexスキャンされるので、
コストが、2000から500まで落ちました。
で、実際に画面を動かしてみると、Hit件数は1万のとき、画面が表示されるまで、3分以上かかります、
パフォーマンスが全然改善していません。
既存の画面を調べてみると、htmlフォーマットで、検索結果をダウンロード幼のファイルとして出力していました。
嫌な予感がしたので、ファイル出力をころしてみると、
秒のオーダーまでパフォーマンスが改善しました。
ファイルIOにボトルネックがあるのは間違いないようです。
しかし、セイゼイ600K 1万行程度のhtmlファイルの出力にしては時間がかかりすぎています。
既存画面の、ファイル出力は自作のProcedureでした(画面はPL/SQL)
嫌な予感がしたので、Procedureを確認すると、
1行出力するごとに、ファイルをOpen/Closeしています。

アホかー

1万回のファイルOpen/Closeって、どんな負荷テストやねん。
ファイルOpen/Closeを1回だけにしたら、応答時間は秒のオーダーになりました。
ちゃんちゃん







