
外部のツールとNotionをつないでいて、同期に時間がかかりすぎると感じたことはないでしょうか。
数百件のデータを扱っているだけなのに、処理が何分も終わらない。夜間に回しているから気づきにくいけれど、確認すると想像より長い。
実際に時間を測りました。読むのと書くので、速さがまったく違います。そして、遅いほうには回避策がありません。
読むのは速く、書くのは遅い
まず、測った数字を並べます。
1件あたりの時間
| 操作 | 1件あたり |
|---|---|
| 行を作る | 約0.57秒 |
| 行を更新する | 約0.69秒 |
| 行をまとめて読む | 100件で0.5秒 |
書き込みは1件ずつで、0.5秒から0.7秒かかります。読み取りは、100件をまとめて0.5秒。桁が違います。
なぜこうなるのか
読み取りには、まとめて取る方法が用意されています。1回で100件まで返ってくるので、件数が増えても回数はそれほど増えません。
書き込みには、それがありません。1件ずつ送るしかないので、件数がそのまま回数になります。
1件ずつ読むと、14倍かかりました
読み取りでも、やり方を間違えると遅くなります。
同じ20件で比べました
30件が入ったデータベースを用意して、2通りの読み方を試しました。
| 読み方 | かかった時間 |
|---|---|
| 1件ずつ20回 | 7.3秒 |
| まとめて1回(30件) | 0.5秒 |
1件ずつのほうが件数は少ないのに、14倍かかっています。
やってしまいがちな形
なぜ1件ずつ読むのか。手元に識別子の一覧があると、それを順番にたどりたくなるからです。
外部のデータを順に見ながら「この行はNotionにあるか」を確認していく。自然な書き方ですが、これが1件ずつの読み取りになります。
先にまとめて全部読んで、手元で突き合わせる。順番を変えるだけで、これだけ変わります。
図にすると、こういう差です
書き込みは、まとめて送れません
読み取りが速いなら、書き込みもまとめられないか試しました。
そういう入り口がありませんでした
複数の行をまとめて更新する方法を探しましたが、用意されていません。何件あっても、1件ずつ送ることになります。
読み取りは1回で100件返ってくるのに、書き込みは1回で1件。この非対称が、同期が遅い直接の原因です。
ページの中身を作るときだけ、例外があります
1つだけ、まとめて送れる場面があります。ページの中に段落などを追加するときです。こちらは1回で100個まで送れます。
ただし、これは1つのページの中身を作る話です。何百件の行を更新する場面には使えません。
1000件だと何分かかるか
測った数字から、規模を換算します。
読むのは秒、書くのは分
| 件数 | まとめて読む | 1件ずつ更新する |
|---|---|---|
| 100件 | 約0.5秒 | 約1分 |
| 1,000件 | 約5秒 | 約12分 |
1,000件の更新で約12分。毎朝これを回していると、12分ぶんの処理が毎日発生します。
そして、そのほとんどは変わっていない行の書き換えです。全件を上書きする作りだと、1件しか変わっていなくても1,000件ぶんの時間がかかります。
途中で止まると、厄介です
12分かかる処理は、途中で止まる可能性もそのぶん高くなります。
そして止まったとき、どこまで書けたのかが分かりません。最初からやり直すと、また12分かかります。
時間が長いこと自体より、この扱いにくさのほうが問題かもしれません。
速さの上限について
速く叩けば速く終わるのか、という点も試しました。
今回の範囲では、止められませんでした
同時に何本も投げて、1秒あたり19件まで出しました。エラーは返りませんでした。
ただし、これで安心してはいけません。公式の開発者向けドキュメントには、平均で1秒あたり3件という上限が書かれています。ビジネスプラン以上は1秒あたり10件です。
測定値と、書かれている数字が違います
短い時間なら多めに通るようです。ただ、書かれている数字のほうを守るのが安全です。今回通ったのは、たまたまかもしれません。
上限を超えると、制限中であることを示す応答が返り、何秒待てばいいかも一緒に返ってきます。その秒数だけ待って、やり直す作りにしておきます。
速く叩いても、根本は変わりません
仮に上限まで使ったとしても、1件ずつ送る事実は変わりません。件数が減らなければ、時間は大きくは縮みません。
速く叩く工夫より、書く件数を減らす工夫のほうが効きます。
遅い同期を速くする順番
効く順に並べます。
1. 変わった行だけ書く
いちばん効きます。全件を上書きするのをやめて、前回と比べて変わった行だけを更新します。
毎日1,000件を回していても、実際に変わるのは数件から数十件のはずです。12分が数十秒になります。
比べるには、前回の状態を手元に持っておく必要があります。その手間はありますが、効果はこれがいちばん大きいです。
2. 読むときは、まとめて読む
次に効きます。1件ずつ取りにいっているところを、まとめて取って手元で突き合わせる形に変えます。
外部のデータを順に見ながらNotionを確認する作りになっていたら、ここを直してください。14倍の差が出た部分です。
3. 識別子を控えておく
前に、検索は作った直後には反映されないという話を書きました。速さの面でも、検索で探すのは不利です。
外部のデータとNotionの識別子を対応づけた表を持っておけば、探す処理そのものが要らなくなります。正確さと速さの両方が改善します。
4. 頻度を下げる
地味ですが効きます。1時間ごとに回していた処理を、1日1回にできないか考えてみてください。
そこまでの鮮度が本当に必要か。必要でないなら、回数を減らすのがいちばん簡単な改善です。
5. 止まったときの続きを作る
件数が多いなら、どこまで書けたかを記録しながら進めます。途中で止まっても、続きから再開できます。
速くはなりませんが、やり直しの12分がなくなります。実際の運用では、こちらのほうが効くこともあります。
よくある質問(FAQ)
測った数字は、どの環境でも同じですか。
今回の測定値です。回線の速さや時間帯で変わります。大事なのは絶対値ではなく、読み取りと書き込みの差が大きいことと、書き込みは件数に比例することです。
複数の行をまとめて更新する方法は本当にありませんか。
探した範囲では見つかりませんでした。ページの中に段落などを追加する場合だけ、1回で100個まで送れます。行の更新には使えません。
同時に何本も投げて速くしていいですか。
今回は1秒あたり19件まで通りましたが、公式には平均で1秒あたり3件(ビジネスプラン以上は10件)と書かれています。書かれている数字を守るほうが安全です。超えると制限の応答が返り、何秒待てばいいかも一緒に返ってきます。
変わった行だけを書くには、どうすればいいですか。
前回の状態を手元に保存しておいて、今回のデータと比べます。値が同じ行は送らない。これだけで、書き込みの件数が大きく減ります。
夜間に回しているので、遅くても困りません。
それなら急いで直す必要はないと思います。ただ、件数が増えたときに気づかないまま時間が伸びていくので、どのくらいかかっているかは記録しておくといいです。
途中で止まったかどうかを、どう判断しますか。
処理の最後に完了の記録を残して、それがあるかどうかで判断するのが簡単です。何件処理したかも一緒に残しておくと、止まった位置の見当が付きます。
全件を上書きしていないか、見てください
毎回すべての行を書き換える作りになっていませんか。実際に変わるのは数件のはずです。変わった行だけを書くように変えるだけで、1,000件なら12分が数十秒になります。