【基本情報の実務】索引は「何にでも付ければよい」ものではない
魔法道具の目録館の管理人から、検索の速さについて相談が届く。
「道具の一覧が10万件を超えたあたりから、名前での検索がとても遅くなりました。データベースに索引(インデックス)を付けると速くなると聞いたのですが、仕組みと注意点を教えてください。何にでも付ければよいものでしょうか」
最後の問いに、先に答えると「違います」である。基本情報の知識がここで力になるのは、索引が何を代償にしているかを言えたときだ。速くなる話だけを渡すと、全部の列に付けたくなる。この記事では、仕組みと代償の両方を整理する。
まず結論:本の巻末索引と、同じことをしている
| 本 | データベース | |
|---|---|---|
| 索引なし | 最初のページから読む | 先頭から1件ずつ照合する |
| 索引あり | 巻末の索引で、ページ番号を引く | 索引で、置き場所を引く |
巻末の索引が速いのは並んでいるからである。五十音順に並んでいるので、目当ての語に、開いた場所からたどり着ける。
データベースの索引も同じでその列の値を、並べた状態で別に持っている。並んでいるものは、半分ずつ絞って探せる。
10万件を先頭から見ると最大10万回の照合になる。並んでいるものを半分ずつ絞ると17回までで届く。
ここまでが速くなる話である。そして、この索引はどこからか出てきたわけではない。
誰かが作って、誰かが保っている。代償は、そこにある。
代償① 書き込みが遅くなる
本の索引は本が完成してから作るので、あとから変わらない。データベースは違う。
道具を1つ追加するたびに、索引にも足す。名前を直したら、索引の並びも直す。
だから索引を付けると、書き込みが遅くなる。読むのを速くする代わりに、書くのが重くなる。
そして索引を5つ付ければ、書き込みのたびに5つ直すことになる。
これが「何にでも付ければよい」ではない、いちばんの理由である。
だから判断は読む回数と、書く回数の比で決まる。
- 目録館のように、検索は毎日、登録は時々——索引が有利
- 絶えず書き込まれて、たまにしか検索しない——索引の維持のほうが重くなる
あわせて場所も取る。索引そのものが、保管しておくデータである。
代償② 絞れない列には効かない
索引が効くのはその条件で、候補がぐっと減るときである。
名前で探すなら、たいてい1件か数件に絞れる。ここは効く。
ところが2種類しか値が無い列——たとえば「使用可/使用不可」のような列だと、半分くらいが該当する。
このとき索引を引いてから、本体を1件ずつ見に行くことになるので、手間が2度になる。最初から全部見たほうが速いことすらある。
だから付ける列は、値の種類が多いものを選ぶ。名前、番号、日付——このあたりは効きやすい。
区分や状態のように、値が数種類しかない列は、単独では効きにくい。
ここは直感と合わないところである。よく検索に使う列だから付ける、とは限らない。よく使ううえに、絞れる列である。
代償③ 条件の書き方で、使われないことがある
付けたのに速くならない——これが起きる原因の1つが条件の書き方である。
索引は並んでいることで速い。並び順と違うものを探すと、使えない。
- 「〜で始まる」——使える。並び順のとおりにたどれる
- 「〜を含む」——使いにくい。どこに現れるか分からないので、順にたどれない
- 値を加工してから比べる——使えないことがある。索引には、加工前の形で並んでいるため
3つ目は気づきにくい。大文字と小文字を揃えてから比べる、空白を取り除いてから比べる——親切のつもりの処理が、索引を使えなくする。
「〜を含む」の検索が必要な場合は索引では解けない。別の仕組みが要る。
だから相談を受けたときはどんな検索をしているかを聞く。「名前で検索」だけでは、まだ決まらない。
方針の例
索引についてのご説明と方針(案)
「何にでも付ければよいか」——違います
速くなるのは読むときで、そのかわり書くときが遅くなります。まずここをお伝えします。
仕組み
本の巻末索引と同じです。索引が速いのは並んでいるからで、五十音順に並んでいるので、開いた場所からたどり着けます。
データベースの索引も、その列の値を並べた状態で、別に持っています。並んでいるものは半分ずつ絞れるので、10万件でも17回までで届きます。先頭から1件ずつだと、最大10万回です。
代償が3つあります
1. 書き込みが遅くなります
道具を1つ登録するたびに、索引にも足します。名前を直せば、索引の並びも直します。索引を5つ付ければ、登録のたびに5つ直すことになります。
目録館では検索は毎日、登録は時々かと思いますので、この点では索引が有利です。登録の頻度が上がるようでしたら、あらためて見直しましょう。
2. 絞れない列には効きません
索引が効くのはその条件で候補がぐっと減るときです。
お名前なら1件か数件に絞れるので効きます。一方「使用可/使用不可」のように2種類しかない列は、半分くらいが該当します。索引を引いてから本体を見に行くぶん、かえって手間が増えることもあります。
よく検索に使う列だから付ける、とは限りません。よく使ううえに、絞れる列です。
3. 条件の書き方によっては、使われません
- 「〜で始まる」——効きます
- 「〜を含む」——効きにくいです。どこに現れるか分からないためです
- 値を加工してから比べる——効かないことがあります
3つ目は気づきにくい点です。空白を取り除いてから比べる、といった親切のつもりの処理が、索引を使えなくします。
ご確認したいこと
- いまの検索は「〜で始まる」ですか、「〜を含む」ですか。
「含む」の場合、索引では解けません。別の仕組みのご相談になります。- 検索のとき、名前に何か処理をしていますか。(空白を取る、表記を揃える、など)
- 名前以外で、遅いと感じる検索はありますか。
進め方のご提案
まず、名前の列にだけ付けます。全部の列には付けません。
そして付ける前と後で、時間を測ります。付けたのに速くならない場合は、上の3つ目に当たっている可能性がありますので、そこから調べます。
遅い検索を特定してから、1つずつ付けるのが確実です。
問いに、先に答えた。「違います」から始めている。
仕組みの説明を巻末索引に寄せた。すでに知っているものに重ねると、説明が短くて済む。
代償を3つに番号を振った。1つだけ書くと、それさえ避ければよいと読まれる。
「よく使ううえに、絞れる列」と書いた。直感と違うところなので、言い切っている。
最後は1つずつ付けて、測るという進め方にした。説明で終わらせず、次の一手を渡している。
作り方の手順
- 問いに先に答える。「何にでも付ければよいか」→違います。
- 知っているものに重ねる。巻末索引。
- なぜ速いかを、並んでいることから説明する。
- 代償を、番号を振って並べる。
- 書き込みが遅くなることを、いちばん上に置く。
- 読む回数と書く回数の比で判断すると示す。
- 絞れない列には効かないと書く。
- 条件の書き方で使われないことを書く。
- どんな検索をしているかを聞く。
- 1つずつ付けて、測るという進め方を渡す。
この場面で効いている基本情報の知識
- 索引——列の値を並べた状態で別に持ち、置き場所を引く
- 読みと書きのつり合い——読むのを速くし、書くのを重くする
- 値の種類の多さ——絞れない列では効かない
- 条件の書き方——加工してから比べると、並び順が使えない
知識そのものより、速くなる話と一緒に、代償を渡せることが、この場面で効いている。
説明で外したくないポイント
- 何にでも付けるものではない。先に答える。
- 巻末索引と同じ。速いのは並んでいるから。
- 索引は、誰かが保っている。そこに代償がある。
- 書き込みが遅くなる。5つ付ければ5つ直す。
- 読む回数と書く回数の比で決まる。
- 絞れない列には効かない。
- よく使ううえに、絞れる列を選ぶ。
- 「〜を含む」は、索引では解けない。
- 加工してから比べると、使われないことがある。
- 1つずつ付けて、測る。