PHPでのOracle利用(16)──索引カスタマイズ(1)
次の問題はインサートの失敗──つまり、ジオメトリカラムの入力に制限が掛かってるらしいのでそれ──をどうにかする事
もう一つはDBの調整だ
とりあえず、現状では格納されたデータを望む形に引き出して加工できるようになった。が、いざ有る程度の情報数を請求すると以下の内容が帰ってくる
Fatal error: Maximum execution time of 30 seconds exceeded in <ディレクトリパス> on line 67
解決策としてはスクリプトで制限時間を定義してしまえばいいのだが、それだと意味が無い。完成したは良いが、PostGISやMySQLに比べると驚くほど速度が遅いのが現状だ
今までテストしていたスクリプトをそのまま(多少細部は違うが)流用しているので、今現在は単純にOracleが遅いことになる。どうにかできないものか
インサート失敗の解決はとりあえず失敗したデータのサンプルが別途保管してあるので、現状でシステムが動かない原因となっているDBの速度を解決しよう
まずは、ジオメトリカラムの設定から考える
一番の遅い原因と思われるuser_sdo_geom_metadataから色々と考えてみよう
INSERT INTO user_sdo_geom_metadata( TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) VALUES ( 'gis_t', 'geom', SDO_DIM_ARRAY( SDO_DIM_ELEMENT('X', 0, 138, 0.0000000000001), SDO_DIM_ELEMENT('Y', 0, 35, 0.0000000000001) ), NULL);
TABLE_NAMEはそのまま、テーブルの名前
COLUMN_NAMEはジオメトリカラム名称が格納される
SDO_DIM_ARRAYでは空間情報のエクステント(要するに、そのジオメトリ空間の広さ)と許容度値が定義されている
許容度値はジオメトリ情報の補完(丸めによる誤差修正)の境界を定義しているらしい
最後に、NULLを挿入している場所は本来SRIDが格納されるべき個所。未定義でもある程度DBが整合性とってくれるらしい
時間超過の問題としては用意する空間が広すぎるのが第一の原因だろうか
現在は世界地図を用意して、その隅っこに打たれた点を探している感じ。無駄が多いし、当然範囲が広いので時間も掛かる
許容度値が細かすぎて、情報が無駄に複雑なのも原因だろう
とりあえず、以下の様な定義に変えてみた
INSERT INTO user_sdo_geom_metadata (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) VALUES ( 'gis_t', 'geom', SDO_DIM_ARRAY( SDO_DIM_ELEMENT('X', 136, 138, 0.00001), SDO_DIM_ELEMENT('Y', 33, 35, 0.00001) ), NULL);
そして実行……変わった気がしない
正確に計測してみる。こんな感じになった
・変更前 30163ミリ秒 ・変更後 30083ミリ秒
…正直、誤差の範囲内で何も変わってねぇ…
同じ情報が同じ要求で返されるPostGIS利用のスクリプトとえらい速度が違う
解決できそうにないんで、次のアプローチに移ってみよう
検索するのに索引が必要。つまり索引の設定で高速化を図れないだろうか?
現在の定義は以下のとおり
CREATE INDEX gis_sp_index ON gis_t(geom) INDEXTYPE IS MDSYS.SPATIAL_INDEX;
ただ、作って居るだけ。これに色々手を加えれないだろうか