LoginSignup
29
25

More than 5 years have passed since last update.

難しいと思ってたRailsのパフォーマンス・チューニングがちょっとしたことで劇的に改善できた話

Posted at

前から任されたら嫌だなーと思っていたパフォーマンス・チューニングのタスクがまわってきて「ついに来たー!イヤー!」と思ったのに、ちょっとしたことで劇的にパフォーマンスが改善して一瞬で終わりましたよ、でも大して自慢にならんね、という話。

そのプロジェクトは全部で12カ国にまたがるウェブサービスを展開していて、問題になっていたのは定期的に出してたレポートの出力パフォーマンスだった。財務諸表のフォーマットに沿ったレポートでしかも統一されたモノではなく、各国の会計基準に合わせたフォーマットになっていた。それはほぼ9種類。もちろん通貨は異なるし、それぞれの国で独自でユーザーに無料特典とかを実施していたので、その会計のルールでは無料特典の扱いが国によって異なるから、ユーザー毎に無料特典分と本当にお金を支払ってサービス利用した分とかを集計したり、結果をchart.jsに渡してグラフ表示が必要な国と不要な国があったりと、とにかくややこしかった。

最初このレポート機能を実装した時はだいたい1,2分で全世界分のレポートが出力できていたらしい。ところが月日が経ってデータ量も肥大化し今ではボタンを押して全てのレポートが出るまで14分もかかっていた。いくらなんでも14分は無いわ、ということで担当エンジニアであるロンドンオフィスのイギリス人エンジニアPがチューニングをしていた。
しかしPは他にいい転職先が見つかったらしく、もうすぐ退職の予定でその最終出社日が間近に迫っていた。もしPが退職までにこれを完了させなければ、私にこの仕事がまわってきそうな、いやーな予感がしていた。ちょくちょくPにチャットで「やっとるか?」と進行状況を聞いていた。Pからは妙にガンバってる風な返信が来るのだが「実はそこまでやる気ない」というPの密かな思いをヒシヒシと感じていた。

で、いよいよデッドラインが近くなって私に声がかかった。「ついに来たか。。。」と暗雲たる気持ちでPから大量の国際会計ルールのドキュメントやらが送らてきたのを眺めていた。そして1時間ほどPとスカイプ会議をした。会議で説明を聞きながらPがハマるのも理解できた。あまりに細かいルールがあり過ぎるのだ。しかもコードはところどころが生SQLで別のところはActiveRecord(ORM)を使っている。
「なんでこんなに統一性が無いんだよ?」と聞くと、あまりに会計ルールが分からなさすぎて、泥縄式に統一感なく完成させたから、ということだった。スパゲッティ・コードもさることながら国際会計ルールも頭痛の種だった。そんな英語聞いたことない、というような会計用語をPのブリティッシュ訛りの英語でガンガン言われてストレスがマックスだった。「まだよく分からないけど今日はここまでにしよう。次回は2日後で」と言ってスカイプ会議を終了した。
会議が終わったついでに、なにげにレポート出力ボタンを押すと過去4年分のデータを14分かけて計算していて「こんなもん知るか」と、かなり投げやりな気持ちになっていた。

ミッションはこの14分かかっている出力パフォーマンスをせめて3分以内にすること。
ありがちなN+1問題とかインデックス張ってないとかの初歩的な部分は全てPがチェック済みだった。もうここまで来たら、データベース設計からコードまで根本的に見直す必要があるかも、と思っていた。

しかしあることに気がついてちょっとコードを変更して、やってみたら1秒足らずのレンダリング時間でレポートが出力されたのだ。
面白いから次回のPとのスカイプ会議まで黙っておいて、会議でPに「ちょっとレポートボタン押してみて」と言った。「え?今?14分かかるけどいいの?」と言いながらPが押すと1秒でレポートが出た。Pは例の放送禁止用語を連発して私に絶賛と罵倒を交互にシャウトした。

もうここまで書いて勘の鋭い方はお気付きかもしれない。
私がやったことは極めて単純。過去の売上確定分の計算処理は最初の1回だけにして、その計算結果はデータに保存しておく。そしてボタンを押したら前回計算して保存しておいたところからの差分だけを処理してレポートに足したのだ。なんで今までバカみたいに過去4年分のしかも全ユーザー分を国別にゴリゴリ計算してたんだよ、と。

まーこの改善策はあまりに基本的過ぎて、声高らかに「1秒にしたんだぜ!」などと自慢できるような話ではない。そして案外こういう基本的なことが抜け落ちているのは誰にでもあること。

この件について別にPがマヌケで私がセンスいい、とか思っていない。逆の立場であれば私もPと同じ状況に陥っていたことは想像に難くない。どんなエンジニアでも「国際会計のルールを全部把握しろ!」「12カ国分の会計レポート出せ!」「ハヨしろ!ハヨしろ!」とやられると目の前のタスクの巨大さから、ついつい近視眼的になってしまう。近視眼的にやらなければややこしい会計ルールをコードに落とし込めない。そうするうちに基本的なことを見落としてしまうのだ。

今回の件ではオイシイところだけ私が奪ってしまったようだが、なかなかに教訓になる出来事だなと感じた。
事情を知らない人は、なんか私がすごい改善をして内容も全部理解してるように見えるようだが、結局私は今でも国際会計ルールは把握できていないし、あのコードのメンテナンスなんてできないし、やりたくもない。

エンジニアの皆様へ

ほとんどのエンジニアには解けるが、下位10%のダメなエンジニアにだけ解けないパズル?」なるものをシリーズ化してパズル1から8まで作成した。もしご興味あれば解いてみてください。
http://tango-ruby.hatenablog.com/entry/2015/11/30/122814

29
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
25