以下の内容はhttps://uga-box.hatenablog.com/entry/2021/03/15/000000より取得しました。


【SQL高速化】遅いクエリを早くした話

たった1回のDBアクセスに0.1秒くらいかかるクエリがあったので調査した

テーブル定義はこんな感じ
f:id:uggds:20210429141633p:plain:w400

緯度経度が格納された位置テーブルと、エリア名などが格納されたエリアテーブル

そして、この2つのテーブルの中間テーブルがあり、これらを結合して検索を行う

クエリは以下

select C.COORDINATE_ID as COORDINATE_ID,
           A.AREA_ID         as AREA_ID,
           A.AREA_TYPE     as AREA_TYPE,
           A.NAME     as NAME
from COORDINATE C
       inner join AREA_COORDINATES AC on AC.COORDINATE_ID = C.COORDINATE_ID
       inner join AREA A on A.AREA_ID = AC.AREA_ID
  and C.LAT_LNG = #{coordinate}

COORDINATEテーブルを駆動テーブルにして、AREA_COORDINATESテーブルとAREAテーブルを結合して検索している

調査時はよくあるクエリで違和感がなかったが、このクエリの実行プランをみると、AREAテーブルのフルスキャンがかかっていることがわかった f:id:uggds:20210429150935p:plain

そして、このフルスキャンが実行時間の中で支配的であるので、フルスキャンをやめるようにしたら速くなりそう

内部結合を減らす

AREAテーブルを駆動テーブルにしてみたりと、いろいろ組み換えてみたが特に変わらず、結果的に内部結合を減らすのが効果があった

もともとのSQLでは内部結合を2回行っていたが、これを1回にしてみた

select C.COORDINATE_ID as COORDINATE_ID,
           A.AREA_ID         as AREA_ID,
           A.AREA_TYPE     as AREA_TYPE,
           A.NAME     as NAME
from AREA A
       inner join AREA_COORDINATES AC on A.AREA_ID = AC.AREA_ID
           and AC.COORDINATE_ID = (
               select COORDINATE_ID
               from COORDINATE
              where COORDINATE.LAT_LNG = #{coordinate})

こうすることによりフルスキャンがなくなり、結果0.0001秒で1000倍速くなった f:id:uggds:20210429152300p:plain




以上の内容はhttps://uga-box.hatenablog.com/entry/2021/03/15/000000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14