バグ修正とデバッグの実例3
導入
新規でマスタからトランザクションを作成する特定の機能の処理が非常に時間がかかり、タイムアウトエラーが発生していることを確認しました。このマスタからトランザクションにコピーする処理は、処理するデータが多くても 300 件程度であるにもかかわらず、時間がかかりすぎるのは異常です。そのため、該当部分を調査することにしました。
問題の特定
対象のテーブルのデータが多い場合、処理時間がオーダー n ではなく増加していくことを確認しました。これは二重ループや LIKE 句などの検索が原因である可能性があります。問題部分の API から呼ばれている処理を確認したところ、表面的には特に問題のある処理は見当たりませんでした。また、実際に動作させてみても、フロントエンドから送信されているデータや内部的に一時的に保持しているデータには異常はありませんでした。
しかし、SQL のログを確認したところ、繰り返し実行される SQL の実行速度が明らかに遅かったため、ロガーを仕込んで実行時間を計測しました。最初に処理全体の実行時間を計測し、二分探索で範囲を狭めていった結果、特定の処理が重たいことが判明しました。その処理では、汎用的なクエリ作成処理で、ID などの一意に定まる項目に対しても LIKE 句を使用して検索していることが分かりました。
修正の実施
汎用的なクエリ作成処理を改め、LIKE 句ではなく、単純一致で検索するように処理を修正しました。
結論
汎用的な処理内容を無理に作成するのではなく、目的のスコープを狭めた関数を定義し、抽象化できる処理のみを抽象化することが重要であると学びました。プログラミング経験の乏しい開発者は処理内容を無理に共通化しようとして、かえって複雑な処理を書いてしまうことがあるため、レビューの際には注意深く見る必要があると痛感しました。
Discussion