毎日、アプリに対して様々なリクエストが投げられるかと思います。そんな中、大量データの入っているクラスに対するリクエストや、クラスに対する検索内容が複雑なリクエストの場合、レスポンスまでかなり時間がかかってしまうことがあります。この様な検索に時間のかかるリクエストを、「スロークエリ」と言います。スロークエリが大量発生すると、アプリユーザー様のイライラを招いてしまうだけではなく、mobile backend システム全体の負荷も高まってしまい、アプリを一時停止させていただく・・・といった大事態に発展することもあります。 今回は上記現象を回避していただくために、スロークエリを発生させないクラス設計方法を、例と共にご紹介したいと思います!
はじめに
スロークエリとは?
普段アプリを使っている際に、「レスポンスが遅い」と感じたことはありませんか?
例えばアプリユーザーが自分の情報を取得するとき、以下の様な場合にレスポンスに時間がかかることがあります。
ユーザー情報を保持しているデータクラス内のデータ数が莫大
ユーザー情報を保持しているデータクラスを複雑な条件で検索
上記2点の理由等で、データの検索に時間のかかるリクエストを、「スロークエリ」と言います。
スロークエリが発生するとどうなるか?
スロークエリが発生すると、第一に、アプリユーザー様のイライラを招いてします。レスポンスが遅くてイライラした経験、誰もが一度はあるのではないでしょうか?
第二に、スロークエリの大量発生によって、アプリが一時停止されることもあります。たかがスロークエリで一時停止!?と思われるかもしれませんが、大量のスロークエリ発生は、該当アプリだけでなくシステム全体の負荷となることもあるのです。その結果、他のユーザー様アプリにまで影響が出てしまうこともあります。
※これはクラウドの弱点でもありますね・・・
悲しい事態を防ぐために
アプリの一時停止はとても悲しい事態ですね。mobile backend ではこの悲しい事態を防ぐために、スロークエリを多く発生させているお客様へ、事前のご案内をさせていただいております。
過去にも沢山ご案内をさせていただいていますが、その中で、クラス設計の改善案をご案内させていただくことも多々あります。
今回は、このクラス設計方法を過去の事例を基にご紹介したいと思います!
【例:カードゲームアプリ】
スロークエリを発生させないクラス設計
スロークエリ発生時のシチュエーション
今回紹介するのは、ゲームアプリでよく見られる、"ギフト機能"に関する検索でスロークエリが発生していた事例です。
ゲーム内で、他ユーザーからアイテムが贈られ、そのアイテムを受け取る際の検索を実施していました。
スロークエリ発生時のクラス・リクエスト内容
下記ギフトカードクラス内を以下のように検索していました。
▼クラス
- 特定のユーザーがまだ所持していないギフトカード
の中でも - カードタイプが"1"かつ、受け取り可能なギフトカード
又は - カードタイプが"2"かつ、カード名が"hogehoge"なギフトカード
▼リクエスト(クエリ)内容
上記条件にマッチするギフトカードと、そのギフトカード数をカウントした結果の二つをアプリ表示していました。
第一アドバイス:カウント方法の改善
今回該当カード数をカウントする処理を行っています。カウント処理は複雑な検索と組み合わせて使用する場合、かなりパフォーマンスが低下することがあります。
下記の様に会員クラスに"cardCount"フィールドを追加していただき、該当ユーザーにカードが発行された場合は、"cardCount"を更新する、といった実装をしていただくと、会員クラス内の該当ユーザーの情報を検索すれば、カード数をすぐに把握することが出来ます。
こういった方法で、頻繁にカウント処理を行わない仕組みを検討していただければと思います!
第二アドバイス:データ構造の改善①
今回の事例の検索条件では、"cardType"の種類によって複数の条件を組み合わせ、検索を実施しています。
"cardType"の種類が限られている場合、クラスを"cardType"ごとに分け(未定の場合も一つの種類として指定)、クラスごとに検索することをお勧めします。
この場合、カード数の合計については、クラスごとに検索してカウントした結果の合算を算出することで、取得することが出来ます!
第三アドバイス:データ構造の改善②
検索条件では、"ownd"と"giftAvailable"フィールドを利用して、ユーザーが既にカードを持っているか・受け取り可能なカードかどうか、を絞っています。
この場合、例えば”未受け取りギフトカード”クラス、"受け取り不可ギフトカード"クラスというクラスにデータを移動させることで、検索範囲を狭めることが出来ます。
また、受け取り不可となったカードデータは定期的にデータを削除することで、アプリ内のデータ数を削減することも出来ます。
注意事項
以上、簡単にクラス設計の改善案を紹介しましたが、クラス設計を変更する上では、APIリクエスト数が増えてしまうという欠点もあります。
アプリの規模やデータ数を考慮した上で最適な方法をご検討いただければと思います!
最後に
今回はスロークエリを防ぐ方法としてクラス設計に注目しましたが、mobile backend にはインデックス追加オプションというものもございます!
データストアで頻繁に実施される検索・取得処理がある場合は、データストアの検索対照となるフィールドに対してインデックスを追加しておくと、処理が効率化され、レスポンスを早くすることが出来ます。
是非インデックスの利用もご検討ください!
管理画面の使い方 : インデックス追加 | ニフクラ mobile backend