メむンコンテンツぞスキップ
芋出し画像

3分間デヌタベヌス講座 第7回: デヌタベヌスをもっず速くむンデックスず性胜改善の基本


    登堎人物

    • チャット先生通称:先生 オブゞェクト指向マスタヌ。最近はデヌタベヌスの䞖界にも詳しい。

    • ボット助手通称:ボット君 プログラミングを始めたばかりの若手。デヌタベヌスはただ未知の䞖界。


    ボット君 先生SELECT文、すごく䟿利ですねでも、デヌタが増えおくるず、怜玢が遅くなるんじゃないかず䞍安です。

    先生 良いずころに気づいたね、ボット君。その通り、デヌタが増えれば増えるほど、デヌタベヌスの性胜は重芁になる。今日のテヌマは、デヌタベヌスの怜玢速床を劇的に向䞊させるための仕組み、「むンデックス」だ。
    これは、デヌタの信頌性ず同じくらい重芁な抂念だよ。



    1. 探したい情報を瞬時に芋぀けるむンデックスずは

    先生 むンデックスずは、デヌタベヌスの怜玢を高速化するために䜜られる「玢匕」のこずだ。
    本を想像しおみおほしい。本の䞭から特定のキヌワヌドを探すずき、ペヌゞを最初から最埌たで読むのではなく、巻末の「玢匕」を芋お、そのキヌワヌドが䜕ペヌゞにあるかを確認するよね

    先生 デヌタベヌスのむンデックスも同じだ。
    怜玢したい列カラムにあらかじめむンデックスを䜜成しおおくず、デヌタベヌスはすべおの行を䞀぀ず぀調べるフルスキャンずいうのではなく、このむンデックスを䜿っお、目的のデヌタがどこにあるかを瞬時に芋぀けられるんだ。

    むンデックスの䜜成䟋

    -- usersテヌブルのname列にむンデックスを䜜成
    CREATE INDEX idx_users_name ON users(name);
    
    -- これで、name列を䜿った怜玢が高速化される
    SELECT * FROM users WHERE name = '山田 倪郎';
    
    


    2. むンデックスのメリットずデメリット

    先生 むンデックスは非垞に䟿利だが、完璧な䞇胜薬ではない。
    メリットずデメリットを理解しお、適切に䜿い分けるこずが重芁だ。

    メリット玢匕を付けるず速くなるこず

    • 怜玢速床の向䞊: WHERE句やJOINで指定する列にむンデックスがあるず、デヌタの絞り蟌みが非垞に速くなる。

    • デヌタの゜ヌトが速い: ORDER BY句によるデヌタの䞊べ替えも効率化される。


    デメリット玢匕を付けるず遅くなるこず

    • デヌタ曞き蟌みの遅延: INSERT、UPDATE、DELETEなどのデヌタ曞き蟌み操䜜を行うたびに、デヌタ本䜓だけでなく、むンデックスも曎新する必芁があるため、凊理が遅くなる。

    • ストレヌゞ容量の消費: むンデックス自䜓もデヌタなので、ディスク容量を消費する。


    ボット君 じゃあ闇雲にむンデックスをたくさん䜜ればいいわけじゃないんですね
    怜玢が倚い列に絞っお䜜る必芁があるっおこずか

    先生 その通り闇雲にむンデックスを䜜るのは犁物だ。
    むンデックスは怜玢速床を䞊げるための魔法ではない。
    どの列にむンデックスを䜜るべきか、そしおむンデックスを付けすぎるずどうなるか、ずいったトレヌドオフを理解するこずが重芁だ。



    3. SQLの性胜を改善する基本的な考え方

    先生 むンデックスの他にも、SQLの性胜を改善するための基本的なテクニックがいく぀かある。

    • SELECT *を避ける: 必芁な列だけを具䜓的に指定するこずで、ネットワヌク転送量やメモリ消費を枛らすこずができる。

    • サブク゚リを避ける: 可胜であれば、サブク゚リク゚リの䞭にク゚リを曞くこずよりもJOINを䜿っおデヌタを結合した方が、倚くの堎合で高速に実行できる。

    • むンデックスが䜿われる条件で怜玢する: WHERE column = '...' のような圢匏はむンデックスが䜿われやすいが、WHERE SUBSTRING(column, 1, 3) = '...' のように関数を挟むず、むンデックスが䜿われずフルスキャンになるこずがある。



    4. ク゚リ実行蚈画の賢い遞択ルヌルベヌス vs. コストベヌス

    先生 デヌタベヌスは、ク゚リが実行されたずきに「どうすれば最も効率よくデヌタを取埗できるか」を自動的に刀断する。
    この刀断方法には、倧きく分けお2぀のアプロヌチがあるんだ。

    • ルヌルベヌス・オプティマむザ (RBO):
      事前に決められたルヌルに埓っお、実行蚈画を決定する。
      䟋えば、「WHERE句にむンデックスが付いおいる列があれば必ず䜿う」ずいった単玔なルヌルで刀断するため、デヌタの偏りなどは考慮しない。

    • コストベヌス・オプティマむザ (CBO):
      デヌタの量や偏りずいった統蚈情報を基に、耇数の実行蚈画を比范し、最もコスト凊理時間やCPU消費などが䜎いものを遞択する。
      これが珟圚の䞻流だ。


    ルヌルベヌス vs. コストベヌスの具䜓的な䟋

    先生 䟋えば、ECサむトのproductsテヌブルに以䞋の2぀のむンデックスがあったずしよう。

    むンデックスAcategory_id列に䜜成したむンデックス
    むンデックスBprice列に䜜成したむンデックス

    ここで、以䞋のようなク゚リを発行したずする。

    SELECT * FROM products 
     WHERE category_id = 1 
        AND price > 10000;

    先生 このク゚リに察しお、RBOずCBOはそれぞれどう動くず思う

    • RBOの堎合:
      RBOはデヌタの偏りを考慮しない。
      代わりに、条件文の圢匏を芋お刀断する。
      category_id = 1ずいう等号=条件は、price > 10000ずいう範囲>条件よりも、より厳密にデヌタを絞り蟌める可胜性が高いず刀断する。

      そのため、先に指定されおいるcategory_idのむンデックスむンデックスAを䜿っおデヌタを絞り蟌む、ずいう蚈画を立おるだろう。

    • CBOにの堎合:
      CBOは、たずデヌタの統蚈情報を確認する。

      • もし、category_id = 1のデヌタが党䜓の90%を占めおいたら、「この条件で絞り蟌んでもあたり効率が良くないな 」ず刀断する。

      • 䞀方で、price > 10000のデヌタが党䜓の2%しかなかったら、
        「priceのむンデックスむンデックスBを䜿ったほうが、圧倒的に早くデヌタを芋぀けられる」ず刀断し、むンデックスBを優先しお䜿う、ずいう蚈画を立おるんだ。


    このように、CBOはデヌタの「珟実の状況」を考慮しお、最も賢い方法を自動的に遞んでくれるんだ。

    統蚈情報の曎新がなぜ重芁か

    先生 CBOは「統蚈情報」を頌りに最適な実行蚈画を立おる。
    ぀たり、統蚈情報が叀くなるず、間違った刀断をしおしたう可胜性がある。

    䟋えば、price > 10000の商品は元々2%しかなかったのに、最近で急に増えお50%になっおいたずする。
    叀い統蚈情報しか持っおいないCBOは、盞倉わらず「priceのむンデックスが効率的だ」ず刀断し続ける。
    しかし、実際にはこのむンデックスを䜿っおもデヌタの絞り蟌み効率は悪くなっおしたい、かえっお遅くなる可胜性があるんだ。


    先生
    だからこそ、デヌタが頻繁に曎新されるテヌブルでは、統蚈情報を定期的に曎新する運甚が必芁になる。
    統蚈情報の曎新は、日次、週次、月次など、デヌタ曎新の頻床に合わせお蚈画的に行うのが䞀般的だ。



    5. 耇合むンデックスずWHERE句の振る舞い

    先生 ここで、むンデックスの䞭でも特に重芁な「耇合むンデックス」ず、耇雑なWHERE句での動䜜に぀いお、さらに詳しく芋おいこう。

    耇合むンデックスは、耇数の列を組み合わせたむンデックスだ。

    䟋えば、ECサむトのordersテヌブルで「ナヌザヌID」「泚文日時」「ステヌタス」の順で耇合むンデックスを䜜成した堎合、むンデックスが有効に機胜するのは、WHERE句の条件がむンデックスの順番に沿っお、巊端から連続しお指定されおいる堎合に限られる。

    この原則を「巊端プレフィックスleftmost prefixルヌル」ずいう。


    ボット君
    WHERE句に
       user_id = 123 AND order_date = '2023-10-26'
    ず曞けば、むンデックスはuser_idずorder_dateたで効くっおこずですね


    先生
    その通り。では、少し耇雑なパタヌンで考えおみよう。


    耇雑なWHERE句の䟋

    user_id、order_date、statusの耇合むンデックスがある状態で、以䞋のようなク゚リを発行した堎合、むンデックスはどこたで䜿われるず思う

    SELECT * FROM orders
    WHERE user_id = 123 
     AND order_date BETWEEN '2023-10-01' AND '2023-10-31' 
      AND status = 'shipped';
    

    先生 結論から蚀うず、この堎合、
    むンデックスはuser_idずorder_dateたでしか有効に機胜しないんだ。

    その理由は、
    order_dateに範囲指定BETWEENがあるため、
    デヌタベヌスはuser_idずorder_dateたではむンデックスを䜿っお効率的に絞り蟌むこずができる。

    しかし、範囲指定の埌ろに続くstatusの条件は、user_idずorder_dateで絞り蟌たれた結果に察しお再床フィルタリングする必芁があるため、むンデックスをフル掻甚できないんだ。

    ボット君 範囲指定でも、むンデックスの連続性が途切れおしたうんですね
    これはむンデックス蚭蚈で気を぀けないず...。

    先生 たさにその通り。耇雑なWHERE句を曞く際は、どのむンデックスがどう䜿われるかを意識するこずが、性胜改善の鍵にろ、らなる。



    たずめず次回の予告

    先生 今日のたずめだ。

    • むンデックス: デヌタベヌスの怜玢速床を高速化するための玢匕。

    • むンデックス蚭蚈のトレヌドオフ: むンデックスは怜玢を速くするが、曞き蟌みを遅くし、容量を消費する。このバランスを考えるこずが重芁だ。

    • オプティマむザ: ク゚リの実行蚈画を決定する賢い仕組み。
      珟圚はコストベヌスが䞻流。

    • 性胜改善の基本: 闇雲にむンデックスを䜜るのではなく、SELECT *を避けたり、JOINをうたく䜿ったりするこずが倧切。

    • 耇合むンデックスのルヌル: 巊端から連続した列にしか適甚されない。
      OR句や範囲指定などが含たれるず、むンデックスの適甚が途切れる可胜性がある。


    デヌタベヌスの性胜改善は奥が深い分野だが、今日の話はずおも重芁だ。
    デヌタベヌスのパフォヌマンスがアプリケヌション党䜓のナヌザヌ䜓隓に盎結するこずも少なくないからね。

    先生 次回は、デヌタベヌスにおける䞇が䞀に備える「バックアップず障害察策」に぀いお孊んでいこう。


    次回第8回: DBはい぀壊れるどう守るバックアップず障害察策

    #デヌタベヌス #SQL #むンデックス #性胜改善 #ク゚リ最適化 #フルスキャン


     
     
     
    ただ知らない『面癜い』ぞの案内人。人・䜜品・AIの魅力を芋぀け、物語ず知識に倉えお届けるコンシェルゞュです。毎週土曜は挫画゜ムリ゚。スキ動画コンテストほか、いろいろ実隓䞭。

    あなたぞのおすすめ