By   2016年2月29日

■ LEFT JOIN が分かっていない!

症状:

Oracle から MySQL(Amazon RDS for MySQL)に移行したら、検索が重くなって使い物にならなくなった。

診断時間:

1時間

原因:

LEFT JOIN が分かっていないため、論理削除しているマスタの結合をすべてサブクエリで行っていた。

例)
SELECT
    *
FROM
    売上データ u
    LEFT OUTER JOIN
    (SELECT * FROM 顧客マスタ WHERE 削除フラグ <> 1) c
        ON u.顧客ID = c.ID;

この場合、顧客マスタのインデックスは全く利用できません。
Oracleでは、削除フラグ <> 1 となる顧客マスタの抽出結果をハッシュテーブルに格納してから結合する(ハッシュジョイン)となり、ある程度のスピードが出るのですが、MySQLではハッシュジョインがサポートされていないため、非常に遅くなっていました。

対応策:

SQLの基本構文の理解ができていない人が、設計・コーディングを行っていたため、システムの全面に同様の問題が存在した。
対応が取れる時間は限られているため、特に問題になっているSQLをピックアップして以下の様に修正を行った。

例)
SELECT
    *
FROM
    売上データ u
    LEFT OUTER JOIN
    (SELECT * FROM 顧客マスタ WHERE 削除フラグ <> 1) c
        ON u.顧客ID = c.ID;

↓ 修正

SELECT
    *
FROM
    売上データ u
    LEFT OUTER JOIN 顧客マスタ c
        ON u.顧客ID = c.ID
        AND 1 <> c.削除フラグ ;

コメント:

SQLの基本構文の理解ができていない人が、設計・コーディングを行っていたため、他にも問題は多数あります。
手の施しようがないですが、サブクエリをなくすだけで実用に耐えるパフォーマンスにはなりました。

しかし、最初からサブクエリをなくしていればコーディング量も格段に減っていました。

10億円規模のプロジェクトの共通仕様に「サブクエリにしなさい」と書かれていたこともあります。
そのプロジェクトを私が見たときは、既に納期遅れで、何十人もの技術者が泊まり込んで、入院する人が何人も出ている状態でした。
(私一人ではどうにもできない状況だったため、手は出しませんでしたが……)

同様の間違いをしているプロジェクトは今でも多数あります。
それを指揮してきたSIerは、20年前後、間違ったまま続けているということです。
そんなSIerを正すよりも、開発の内製化を行った方が効率的なのです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です