■ 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を正すよりも、開発の内製化を行った方が効率的なのです。