Eloquentで発行されるSQLがサブクエリ全開だった

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

先日こんなことが発生しました。

LaravelのEloquentで発行しているSQLが突然遅くなった。今まで数秒で終わってた処理が1分ぐらいかかってる。

あれ、何だこれと思いdd()メソッドでSQLを確認、EXPLAIN取得したらこんな感じでした

+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+
| id   | select_type        | table                | type   | possible_keys                                                                           | key                                           | key_len | ref                                       | rows  | Extra       |
+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+
|    1 | PRIMARY            | xxxxxxxx           | ALL    | NULL                                                                                    | NULL                                          | NULL    | NULL                                      | 20859 | Using where |
|    5 | DEPENDENT SUBQUERY | xxxxxxxx   | ref    | xxxxxxxx          | xxxxxxxx       | 9       | func                                      | 1     | Using where |
|    5 | DEPENDENT SUBQUERY | xxxxxxxx            | eq_ref | PRIMARY                                                                                 | PRIMARY                                       | 8       | xxxxxxxx | 1     | Using where |
|    4 | MATERIALIZED       | xxxxxxxx            | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 19    | Using where |
|    4 | MATERIALIZED       | xxxxxxxx      | ref    | xxxxxxxx                | xxxxxxxx           | 8       | xxxxxxxx                   | 182   |             |
|    3 | MATERIALIZED       | xxxxxxxx       | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 23    | Using where |
|    3 | MATERIALIZED       | xxxxxxxx | ref    | xxxxxxxx | xxxxxxxx | 8       | xxxxxxxx              | 155   |             |
|    2 | DEPENDENT SUBQUERY | xxxxxxxx        | ALL    | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                                      | 30    | Using where |
|    2 | DEPENDENT SUBQUERY | xxxxxxxx  | ref    | xxxxxxxx    | xxxxxxxx   | 8       | xxxxxxxx               | 706   | Using where |
+------+--------------------+----------------------+--------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+-------------------------------------------+-------+-------------+

DEPENDENT SUBQUERYでちゃってるー。。。

以下でも紹介されてますが、DEPENDENT SUBQUERYはかなり遅い。

nippondanji.blogspot.com

クエリ組み立ててる部分を見直して最終的には以下な感じに。

+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+
| id   | select_type  | table                | type | possible_keys                                                                           | key                                           | key_len | ref                          | rows  | Extra       |
+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+
|    1 | PRIMARY      | xxxxxxxx           | ALL  | NULL                                                                                    | NULL                                          | NULL    | NULL                         | 20923 | Using where |
|    5 | MATERIALIZED | xxxxxxxx            | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 65    | Using where |
|    5 | MATERIALIZED | xxxxxxxx   | ref  | xxxxxxxx          | xxxxxxxx        | 9       | xxxxxxxx      | 125   |             |
|    4 | MATERIALIZED | xxxxxxxx            | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 19    | Using where |
|    4 | MATERIALIZED | xxxxxxxx      | ref  | xxxxxxxx                | xxxxxxxx           | 8       | xxxxxxxx      | 182   |             |
|    3 | MATERIALIZED | xxxxxxxx       | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 23    | Using where |
|    3 | MATERIALIZED | xxxxxxxx | ref  | xxxxxxxx | xxxxxxxx | 8       | xxxxxxxx | 155   |             |
|    2 | MATERIALIZED | xxxxxxxx        | ALL  | PRIMARY                                                                                 | NULL                                          | NULL    | NULL                         | 30    | Using where |
|    2 | MATERIALIZED | xxxxxxxx  | ref  | xxxxxxxx    | xxxxxxxx   | 8       | xxxxxxxx  | 706   |             |
+------+--------------+----------------------+------+-----------------------------------------------------------------------------------------+-----------------------------------------------+---------+------------------------------+-------+-------------+

ORMって使いこなすと便利だけど、複雑な条件組み立てるとなかなか難しいなぁと思う今日このごろ。

ってこの記事を書きながら色々調べてたらEXPLAINもEloquentでとれるのね。。。知らなかった。。。

www.amitmerchant.com

世の中知らないことだらけです。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

CloudFrontの多段構成はできないんだったなぁ

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

CloudFrontの導入をぼーっと考えていたのですが、そういえば昔CloudFrontの導入でうまく行かないことがあったなとふと思い出したのでここに書きます。

事の発端は、SaaS系のAPIをコールする中間にCloudFront入れようってなったのですが、なんか403が返却されるって感じでした。

あれなんだろうと思って色々調べてたのですが、外部のSaaSがCloudeFrontを使ってるっぽく、自分のところでもCloudFront入れると多段構成になっちゃうからダメそうって結論になりました。

qiita.com

qiita.com

上記みたいな感じで調査されてる方もいて、ヘッダーをごにょごにょすればいけるっぽいです。

結局「使ったこと無いけどいい機会だからFastly入れよう」って導入してうまくいったのですが、意外と公式のドキュメントにも記載されてないことってあるのねってその時思いました。 (もしかしたら自分が調べきれてなかっただけかもw)

CDNの導入は計画的に。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

キャリアLTをやってみました

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

昨年の11月末以下のLTを行いました。

cellpromote.connpass.com

外部・内部の方含めて30名ほどが参加されるLT会になりました。

LTのテーマとしては、クライアントワーク、自社開発、フリーランスという異なったキャリアで今までどんなことをしてきたのか、どういう経緯でそのキャリアを積む事になったのかを発表していただきました。

自分は自社開発の立場で発表をさせていただいたのですが、こういった形で今までのキャリアを振り返る機会ってなかったので為になったなと思います。

クライアントワーク(通称SES)と言われているキャリアが世間的にはネガティブなイメージがあると思います。 ですが、色々な方の話を聞くとクライアントワークって悪くないんじゃない?と最近思ってます。

うまくこのクライアントワークのキャリアを活用すると、フリーランスのメリットを得つつエンジニアとしてのキャリアが積めるんじゃないかなと。

一般的なエンジニアって異なった環境を経験したいってなった場合、転職 or 社内転職っていう選択肢になると思います。 メガベンチャーみたいな会社だと社内転職で期待している新しい環境での経験が積めるかもですが、まぁそんなにうまくは行かないのが世の常。 で、転職ってなるとそれこそ次行く会社が本当に期待している経験できるかなんてのも海のものとも山のものともみたいな。

当然クライアントワークだってそんな簡単ではないですが、うまく活用することで少なくともこの異なった環境を経験するっていう部分では一番大きなメリットを得られるんじゃないかなって思ってます。

エンジニアと営業間の連携が重要になってきたり、会社の方針とかがエンジニアに寄り添ってるかだったり色々な変数はあると思いますが世の中ですごいネガティブな印象になってるクライアントワーク(SES)ってそんなに悪いもんじゃないんじゃないっていう。

まぁとはいえエンジニアとして活躍するには、基礎を学び、身につけて、技術を使って課題を解決っていうとてもベーシックな部分が重要になるとは思いますが。

セルプロモートに入って色々な方とお話ができて勉強になるなと思ったこの今回のLTでした。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

サーバントリーダーシップ

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

昨今よく話題にになるこのサーバントリーダーシップ、すごく参考にしてます。

www.servantleader.jp

サーバントって意味は「召使い」「奉仕者」って意味らしいのですが、かといってメンバーの言いなりになるって意味ではないし、いかにメンバーのパーソナリティに応じて寄り添うマネジメントってことだと思うのですが、逆のリーダーシップの意味で使われる「支配型リーダー」

支配型リーダーは、競争社会を生き抜き、組織の中でうまく立ち回ってきたタイプの人が多いでしょう。自分の地位がとても重要で、常に自分の能力を磨き他の人に差をつけます。それがリーダーとしての自信にもなり、部下やメンバーに命令したり一方的に説明します。

こういうのもちゃんと理解しないといけないなと最近思ってきました。

別に支配することが重要ではないと思うのですが、昨今の多様化っていうものに無理やり合わせようとすると今度はマネージメントする側が疲弊しちゃう。

メンバーとの関係性の作り方次第だと思うのですが結局はバランスが重要なんだろうなと。

こんな記事がありました。

q.livesense.co.jp

すごく読んでてわかるなぁって感じでした。

以前システム開発が複雑になってきてるって話をしたのですが、組織マネージメントまで複雑になってきているかも?

logmi.jp

自分はセルプロのミッション「次の世代をプロモートする」に共感して入社してるってところもあるので、次世代のためになるのであればエンジニアとしても頑張るし、管理職としても頑張りたいなんて思ってますが、こうやって思えてる時点で幸せなんだろうなと。

世の中大変なことだらけだし、どんどん複雑怪奇になってきてるし、物事の進歩も早すぎるし、AIはすごいし、もうっ!って感じ。

サーバントだろうが支配型だろうが、人と人のつながりを意識して色々進めるってのが重要だよねって思いつつ、まぁそんなうまく行かないけどどうやったら良くなるんだろうっていうのは常に意識しようと思う今日このごろ。

とりあえず今思うことを吐き出したところで、今日はここまで。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

世界一流エンジニアの思考法を読んでみた2

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

前回もお話しましたが、巷で話題になっていた以下を読んでみました。

books.bunshun.jp

前回は意思決定はその場で行うみたいな話をしました。

今回自分が勉強になったと思うのが「不確実性を受け入れよう」です。

重要なのは以下の3つで、これをベースに不確実性を受け入れようとのこと。

1.「フィードバック」を歓迎するムードを作る

2.「検討」をやめて「検証」する。

3.「早く失敗」できるように考える。

この2番の「検討」をやめて「検証」するがわかり味が深いなと。

アーキテクチャやツールが数種類あってどれにするか決めあぐねているパターンがあるとしたら、意思決定は簡単だ。答えは「どちらでもいい」。趣味で選べばよい。なぜなら圧倒的に差があるのなら、決めあぐねるはずがないので、どちらを選択しても大差はないのだ。

まぁよくある話だなと思いました。

やる前に色々検討して、時間だけが過ぎていく。結局決まったときには時すでに遅しみたいな。さっさと「検証」してフィードバックを得てそれから改善するってのが圧倒的スピードと成長につながるんだなと。

某会社が掲げてるビジネスプロセスに「仮説→実行→検証→仕組化」ってのがありましたが、仮説をスピーディーにかつ複数たてておいて、実行するのが大事なんだろうなって今更思いました。 (この某会社に11年務めてたのに、今更理解するっていうw)

個人的に、日本は失敗に対するフィードバックがネガティブな物が多い印象なので、ここらへんはもしかすると海外とは文化が違うのかもですが、少なくとも自分の身の回りでお仕事されてる方とはよりポジティブなフィードバックとスピード感を持って仕事ができたらなぁなんてよく思います。

まぁそんな簡単じゃないけど。

今回はこの辺で。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

世界一流エンジニアの思考法を読んでみた1

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

巷で話題になっていた以下を読んでみました。

books.bunshun.jp

個人的にものすごく勉強になりました、と同時に世界一流エンジニアは、振る舞いが一流なんだなと思いました。

面白いなと思ったのがこちら。

「準備」「持ち帰り」をやめてその場で解決する。日本では、会議というと、事前の準備をし、終わった後に議事録を書いたりして様々な課題を検討しないと行けない状況だった。インターナショナルチームを観察していると、彼らは常に「会議の場」だけで完結する。ざっくりとしたアジェンダ(検討事項)はあるが、準備に時間をかけて会議に臨むことは一切しない。

これはよくあると思うのですが、会議の前に事前にアジェンダ準備して、会議でディスカッションして、各自のToDoまとめて、持ち帰って、再度会議みたいなのが一般的だと思います。 ですがこの本の中で説明されていたのは、「宿題」「持ち帰って検討すること」はほぼなく、「意思決定」はその場で行われるとのことでした。

「会議の時間内で完結する」

これを参加者が全員意識して、会議の時間内で決定する。「会議の時間を価値の高いものにする」っていう考え方が根付いている、それを行うように訓練されているっていうのがとても面白かったです。

ただ、すぐにこれができるかって言うと多分できないんだろうなと。

「最初どれぐらい準備をしなくてもいいのかが摑めなかったら、いっそ準備無しでどこまでできるか試してみるとよいだろう」 もし、それで全くできない場合は「余計なこと」を頑張りすぎている可能性が高いとのことなので日頃の業務から不必要なものをできるだけ減らしていく練習をするのが良い。

確かに、日々やっている業務ってこれをやめたらどういう影響出るかわからないからとりあえずやってるってのが多い気がする。

以下に無駄なことをなくせるか、「Be Lazy」っていうキーワードがあると思うけど、「最小の動きで、最大のインパクト」が出せるかどうかが重要なんだろうなって思いました。(なかなかできないけど)

他にも勉強になった内容が色々あったので、次回もご紹介させていただこうかなと思います。

今回はこの辺で。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz

オプショナルチェーンって便利だけど

セルプロモート株式会社で、新規自社プロダクト開発を担当してますsasamonと申します。

フロントエンドの開発をしてるとお世話になるのがオプショナルチェーン(?.)だと思います。

developer.mozilla.org

最近こんなことが発生しました。

本番だと発生しないのに、ローカル環境だけフロント側でCannot read properties of nullが発生しちゃう。

なんじゃこりゃーとメンバーと話ししてたのですが、要するに以下が発生してました。

本番だとDBのデータがちゃんと登録されてるんだけど、ローカルだとデータ整備不足でデータが入ってない箇所がある。

もうカ◯ジで言う「ぐにゃあああああ」って感じ。

で、まずはオプショナルチェーンで対応し、今進めている開発をやりながらちゃんとデータ整備しようねとなりました。

このオプショナルチェーン便利は便利なのですが使い方を間違えるとエラーをもみ消すことになっちゃう。。。

以下の記事もあるように使いすぎはあかんよと。

dev.to

本来であればきちんとデータとコードの整合性が取れる状態でオプショナルチェーンを使おうねって話だけど、安易に使っちゃうと取り返しがつかなくなって後でしっぺ返しを食らうなと思いました。

ちゃんとデータ整備して、整合性が取れる環境を作ろう。

頑張ろう俺。

セルプロモート株式会社では以下からエンジニアを募集してます、興味がある方はぜひご覧いただければと!

cellpromote.biz