こんにちは!データベースの世界へようこそ。
今日は、PostgreSQLを使っているといつか必ずぶつかる「ちょっと困った大きなデータ」の話をしましょう。
データベースにデータを保存するとき、私たちはつい「とりあえず何でも入るでしょ!」と思いがちですよね。でも、システムが成長してくると、ある日突然、パフォーマンスがガタ落ちして「あれ?なんで?」と焦る経験を誰もが一度はするものです。
その犯人の一人が、TOAST(トースト)という仕組みなんです。今日はこの「食いしん坊な仕組み」と、どう仲良く付き合っていけばいいのかを紐解いていきましょう。
—
1. 「荷物運び」で考えてみよう
想像してみてください。あなたは引っ越し屋さんです。
トラックに荷物を積み込むとき、ダンボール箱一つひとつに収まるものなら、サクサク運べますよね。これがデータベースの「普通の列(数値や短い文字列)」です。
ところが、もし「ピアノ」や「クローゼットまるごと」のような巨大な荷物が混ざっていたらどうでしょう? トラックのスペースを占領してしまって、他の小さな荷物が全然載らなくなりますよね。
PostgreSQLにとって、この「巨大な荷物」がTOAST(The Oversized-Attribute Storage Technique)の対象です。
PostgreSQLのルールとして、「1行のデータは8KBまで」という制限があります。この制限を超えそうな巨大なデータが来ると、PostgreSQLは気を利かせて「よし、こいつは別の大きな倉庫(TOASTテーブル)に追い出して、元の場所には『倉庫のどこにあるかのメモ』だけ置いておこう!」と判断します。これがTOASTの正体です。
—
2. 実は「しきい値」を調整できるんです
この「追い出すかどうか」の判断基準となるのが「しきい値」です。デフォルトではだいたい2KBくらいで「あ、これちょっと大きいから倉庫行きね!」と判断されます。
でも、たまにこれが裏目に出ることがあるんです。
「そんなに大きくないのに、いちいち倉庫まで出し入れしてたら手間がかかるよ!」というデータまで倉庫送りにされてしまうと、逆に読み込み速度が落ちてしまうこともあります。
そんなときは、テーブル定義の時にこうやって教えてあげましょう。
ALTER TABLE your_table ALTER COLUMN your_column SET STORAGE EXTERNAL;
こうすることで、「とりあえず圧縮しないで、そのまま外部に置いておいて!」といった細かい指示が出せます。状況に合わせて「倉庫の使い分け」ができるようになると、データベースはぐっと賢くなりますよ。
—
3. インデックスの「見落とし」に注意!
ここが一番の落とし穴なのですが、「TOASTに追い出されたデータは、検索の時に見えにくい」という性質があります。
例えば、巨大なテキストデータを検索対象にしてインデックスを貼ろうとすると、PostgreSQLは「えっ、中身が倉庫にあるから、わざわざ倉庫まで確認しに行かないと検索できないよ…」と悲鳴を上げます。
結果として、以下のようなことが起きます。
- 検索が極端に遅くなる(毎回倉庫まで荷物を取りに行っているようなもの)
- インデックスのサイズが肥大化する
- そもそも巨大なカラムにはインデックスが効かない(あるいは効率が悪い)
もし、「このデータを使って検索をバリバリかけたい!」という場合は、TOASTに頼るのではなく、「全文検索エンジン(Elasticsearchなど)」に任せるか、「検索に必要な部分だけを別のテーブルに切り出す」といった設計の工夫が必要です。
—
最後に:データベースと仲良くするコツ
データベース設計は、いわば「整理整頓」です。
すべてのデータを一つのテーブルに詰め込もうとせず、「これは頻繁に使う短いデータ」「これは滅多に見ないけれど巨大なデータ」と、荷物の種類ごとに置き場所を考えてあげる。そうすると、データベースは驚くほど軽快に動いてくれるようになります。
TOASTは決して「悪者」ではありません。むしろ、私たちが巨大なデータを扱えるように支えてくれる「縁の下の力持ち」です。その仕組みを少しだけ理解して、うまく付き合っていきましょうね。
また次の記事で、現場で使えるちょっとした小ネタをお届けします!何か気になることがあれば、いつでもコメントしてくださいね。
コメント