dropout26
@dropout26

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Firestoreでクエリを呼び出す際にlimitを入れると早くなるか

解決したいこと

現在、Firestore上を検索するコードを書いています。
そこで疑問なのですが、クエリを呼び出す際にドキュメント全体のクエリを取得する事はページの表示速度の低下につながりますか?

例えば10000件のドキュメントがある場合に、

let q = query(collection(getFirestore(), "users"), orderBy("lastlogin", "desc"));

if (searchWord) {
  q = query(q, where("char", "==", searchWord), limit(3));
}

のように10000件のドキュメントを変数に格納してから操作すると遅くなりそうなのですが、どうなのでしょうか。
引数に必ずlimit()を入れて少ないクエリを呼び出す方がドキュメントが膨大になった際に表示速度が早くなるのかと思い、現在は後述のソースコードの通りに書いています。

そもそもクエリが一体どういうものなのかすら理解しておらず、不勉強で申し訳ありませんがご回答いただけたらと思います。

該当するソースコード

import { query, where, startAfter, limit, getDocs, getFirestore, collection, orderBy } from "firebase/firestore";

const getAllData = async (lim, lastSnapshot, searchWord) => {
  let nextSnapshot = "";
  let q = query(collection(getFirestore(), "users"),
    orderBy("lastlogin", "desc"),
    limit(lim));
  if (searchWord == "" && lastSnapshot != "") {
    q = query(collection(getFirestore(), "users"),
      orderBy("lastlogin", "desc"),
      limit(lim),
      startAfter(lastSnapshot));
  } else if (searchWord != "" && lastSnapshot == "") {
    q = query(collection(getFirestore(), "users"),
      where("char", "==", searchWord),
      orderBy("lastlogin", "desc"),
      limit(lim));
  } else if (searchWord != "" && lastSnapshot != "") {
    q = query(collection(getFirestore(), "users"),
      orderBy("lastlogin", "desc"),
      where("char", "==", searchWord),
      limit(lim),
      startAfter(lastSnapshot));
  }
  try {
    const querySnapshots = await getDocs(q);
    if (querySnapshots.docs.length >= lim) {
      nextSnapshot = querySnapshots.docs[querySnapshots.docs.length - 1];
      return { "BuffData": querySnapshots, "nextSnapshot": nextSnapshot };
    }
    return { "BuffData": null, "nextSnapshot": "" };
  } catch (e) {
    console.log(e);
  }
}

export { getAllData }

自分で試したこと

クエリについて調べたところ検索用のインデックスのようなものと理解しましたが、そも検索できるという事は10000件のドキュメント全体を含んでいて相当なサイズになっているのかなと思い当たり、今回質問に至った次第です。
Firestore関連の投稿をされている方々のものを見てみると、q = db.collection("users")としていったんコレクションを取得されている方もいらっしゃるので、やっぱりこれでいいのかなとも考えています。

0

2Answer

多分先に簡単なデータベースの仕組みを見たほうが良いと思います。
Firebaseは一般的なSQLベースのデータベースではありませんが、基本の考え方は一般的なSQLベースのデータベースを元にしていると思うのでまずそっちをやったほうがイメージが掴みやすいと思います。

例えば

また、Firebaseは従量課金なので適当に毎回全部のレコードを読み込むなどしているとすぐに1日の無料枠を超えたり、有料アカウントならどんどんお金がかかります。(なので遅いとか早いとか以前に適切にlimitかpaginationしたほうが良い)

0Like

Comments

  1. @dropout26

    Questioner

    SQLの勉強をした方がよいのですね、ためになります。
    Firebaseは従量課金制なので、適当に検索させてはだめだよねという思いから今回質問に至ったという経緯もありました。
    回答ありがとうございます!

前回の追加質問にまだ答えてなくてすみません。
(ちゃんと答えると面倒だったので。いずれ。)

根本的なこととして、ここでいうクエリとはDBに対して行いたい操作そのものを表現しており、その結果得られるデータとは区別してください。

そういう意味では「クエリを呼び出している」のは、

let q = query( /* ... */ );

ではなく、

await getDocs(q);

ここです。

ここで与えているqlimitが適用されていれば、基本的にパフォーマンスには響かないはず。

0Like

Comments

  1. @dropout26

    Questioner

    なるほど! 大変わかりやすい回答ありがとうございます!
    確かによく考えてみれば、クエリを宣言する間はDBに対して何か操作をしているわけではありませんね。

Your answer might help someone💌