「あとからインデックス追加したらサイトが止まった…」そんな悲劇を防ぐ魔法の言葉
こんにちは!データベースの世界にどっぷり浸かって十数年、エンジニアのブログへようこそ。
皆さんは、Webサービスを運営していてこんな経験はありませんか?
「検索が遅いから、インデックス(索引)を追加しよう!」と意気込んでコマンドを叩いた瞬間、なぜかサイトが応答しなくなって、ユーザーから悲鳴の連絡が届く……という冷や汗ものの体験。
実はこれ、PostgreSQLを触りたての頃、僕も何度もやらかしました。今日は、そんな「悲劇」を未然に防ぐ、オンライン環境の救世主「CONCURRENTLY(コンカレントリー)」というオプションについて、お話ししたいと思います。
—
「インデックス追加」は、図書館の模様替え?
そもそも、インデックスを追加するって、どんな作業なんでしょうか。
例えるなら、「めちゃくちゃ忙しい図書館の棚を、営業中に整理整頓する」ようなものです。
普通にインデックスを作ろうとすると、PostgreSQLは図書館の棚全体に「工事中」のバリケードを貼って、誰にも本を貸し出さないようにしてしまいます。
これだと、たった数秒の作業でも、利用者は「あ、閉館してる!?」と困ってしまいますよね。これが、サイトが止まってしまう原因です。
そこで登場!「CONCURRENTLY」の魔法
そんな時、コマンドの最後にポチッと`CONCURRENTLY`と書き加えるだけで、すべてが解決します。
CREATE INDEX CONCURRENTLY idx_users_name ON users(name);
この言葉を添えるだけで、PostgreSQLはこんなふうに動いてくれます。
1. 「バリケードは貼りません!」:棚を整理している間も、お客さんは普通に本を探せます。
2. 「二段階で準備します!」:一度で完成させようとせず、まずは裏でこっそりリストを作り、最後にサッと本番の棚に反映させる、という丁寧な手順を踏んでくれます。
つまり、「お客さんに気づかれないように、裏でこっそり工事を終わらせる」ことができるようになるんです。これ、すごくないですか?
—
知っておいてほしい「2つの注意点」
ただ、魔法にはちょっとした代償もあります。これを知っておかないと、後で「あれ?」となるので、ぜひ覚えておいてくださいね。
- 時間が少しかかる:
裏でコソコソ作業をする分、普通に工事するよりも、インデックスが完成するまでの時間は少し長くなります。でも、サイトが止まるよりはずっとマシですよね!
- トランザクションの中では使えない:
「`BEGIN;`」と「`COMMIT;`」で囲った中では実行できません。これだけは、コマンドをそのまま直で叩くようにしてくださいね。
—
まとめ:本番環境では、これが「お作法」
駆け出しの頃は、つい勢いで「早くインデックスを作らなきゃ!」と焦ってしまいがちです。でも、多くの人が利用する本番環境では、「サービスを止めないこと」が何よりも優先される技術者の優しさです。
明日からインデックスを追加するときは、ぜひこの`CONCURRENTLY`を思い出して、コマンドにそっと添えてみてください。
「あ、今の作業、全然ユーザーに影響なかったぞ!」という安心感を覚えたら、もう立派なPostgreSQL使いの仲間入りです。
皆さんのデータベース運用が、トラブルなく快適なものになりますように。また次の記事でお会いしましょう!
コメント