質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

Q&A

解決済

1回答

2743閲覧

非クラスター化インデックスでもソートは早くなりますか?

kare-

総合スコア1

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

0グッド

0クリップ

投稿2021/07/05 12:04

編集2021/07/05 12:44

プログラミング初心者です。
現在個人でシステムを作成しており、現在のデータは数百行しかありませんが、将来的には数千行、数万行になるかもしれないテーブルがあります。
##困っていること

様々な条件でソートをしたいのですが、使用しているデータベースのスペックが低いので、処理の速さと負荷の大きさが気になります。
※どのソートも一つの列に対してソートします
##環境
使用データベース
・SQL Server (Azure SQLServer)
・Azureサービスでメモリ容量など詳細を見ることはできないのですが、Freeプランを使用しています
・Azure Database
・容量 250GB ※将来増量予定

テーブル定義 ※将来的に数千~数万行を想定

ID nvarcahr(450) 主キー Title nvarchar (450) ViewCount int decimal(20, 0) //ソートしたい列 LikeCount int decimal(20, 0) //ソートしたい列 CommentCount int decimal(20, 0) //ソートしたい列

##疑問点・調べたこと

調べてみると、**インデックスを付けるとその列で『データが並んで保存される』**ので、ソートの処理が早くなる、といった旨の記事を読みました。

より調べてみると、インデックスには種類があり、ここで指しているインデックスは『クラスター化インデックス』なのではと思っております。

しかし、『クラスター化インデックス』は複数個付けることができず、今回は複数列に対してインデックスを付けたいので足りません

そこでもっと調べてみると、『非クラスター化インデックス』は複数付けることができることがわかりました。
しかし、この**『非クラスター化インデックス』は、『データを並び替えて保存しない』**ということで、今回のソートをする目的でつけても、処理が早くなる、負荷が減るといった風にはならないのではと心配しております

とても初歩的な質問かもしれないのですが、どうか教えて頂けないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kare-

2021/07/05 12:28

申し訳ございません、テーブル定義とタグの追加をしようと思います。 ご指摘ありがとうございます。
guest

回答1

0

ベストアンサー

図で確認したほうが理解しやすいと思うので、例示を出します。
例えば、質問本文のテーブルがクラスターインデックス付きでこのように保存されているとします。

イメージ説明

厳密には違いますが、データベースのファイルには図の様にid順に保存されています。
行はexcelでいう行番号です。
クラスターインデックスの特徴は、あとからどのようなidの値のレコードをinsertしても、保存するデータはid順に並ぶのが特徴です。idが 10 -> 40 -> 30 -> 20 -> の順にレコードをinsertしても、保存するデータは図の様にid昇順に記録されます。

これに対して非クラスターインデックスはインデックス対象の列と行番号のペアをインデックス対象の列の昇順で本表とは別領域に記録します。イメージとしては以下の様になります。

イメージ説明

データそのものを並び替えて保存するのではなく、インデックスの元となる値の順に行番号を保存しています。

例えばview_countが5000以上のレコードを抽出したい場合、本表で抽出するにはテーブル全体を走査しないといけませんが、非クラスターインデックスを参照するとview_countが5000の境界がすぐわかります。境界以降のデータで、行番号と同じデータをそのまま出力すれば良いわけです。行番号の探索時間はpkを探索する時間よりも短いです。

数百行程度のデータだと効果の実感が薄いですが、数万行、数百万行のデータになると顕著に効果が出てきます。
質問文の要件だと、非クラスターインデックスを view_count, like_count, comment_count それぞれで作成すると検索効率が格段に上昇すると思います。

おまけ:オーダ記法での探索コスト

非クラスターインデックスなしでview_countを条件に検索するコスト:Ο(n)
非クラスターインデックスありでview_countを条件に検索するコスト:Ο(log(n))
(内訳)
非クラスターインデックスで view_count = n や view_count > n を探索するコスト:Ο(log(n))
非クラスターインデックスでマッチしたレコードからデータ本体を取得するコスト:Ο(1)
n > log(n) なので、非クラスターインデックスありの方が格段に速くなります。
(例えばn = 100,000 であれば log(n) = 17 くらいです。6000倍くらい早くなる計算です)

投稿2021/07/05 15:45

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kare-

2021/07/05 16:23 編集

ありがとうございます! 非クラスター化インデックスも、インデックス対象の列の順で保存されてるんですね。 それだとソートする際は非クラスター化インデックスの有無で格段に効率が変わりますね。 オーダ記法という概念?も初めて知りました! 独学で勉強しているので、正直こういった単語を知らず検索が中々むつかしい状況でしたので大変助かります。 6000倍のくだりも感動しました。 プログラミングって知識一つで劇的に効率が変わるのが面白いですね! 表まで作って下さり、初心者の私にもわかりやすく教えてくださりありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問