夏椰の東屋

- お遊び記録 -

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  108  : 記事  1  : コメント  3916  : トラックバック  30

ニュース


落書きしてね♪

IAM
僕がとった写真です。
ご自由にお使いください。

フィードメーター - 夏椰の東屋 track feed
広告


記事カテゴリ

書庫

日記カテゴリ

Other Site From Kaya

今回は久々にSQLServer2005で遊んでみました。
ターゲットにしたのは付加列インデックスです。


まずは対象となるテーブルの作成をします。

CREATE TABLE [dbo].[TestTable1](
    [id] [int] NOT NULL,
    [dt] [datetime] NULL,
    [value] [varchar](max) COLLATE Japanese_CI_AS NULL
) 

次にデータを1,000,00件追加します。
ここで使用しているgenerate_seriesについてはこの記事で書いたものを使用しています。
またNEWID()についてはこの記事を参照してください。

insert into TestTable1 
select num, cast('2007/01/01' as datetime) + num*10, '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' 
+ cast((select num from ( select top 1 NEWID() as nid , num from generate_series(1,1000,1) order by nid) t) as varchar) from 
generate_series(1,100000,1)

この状態で2つのSQLを発行します。
まずはインデクスの作成をしない状態でSQLを発行し、テーブルスキャンの状態でどのぐらいの負荷がかかるかを見てみます。
1つ目のSQLはid列、dt列をテーブルから絞り込み条件なしで取得するSQLで、
2つ目のSQLはid列、dt列をテーブルから絞り込み条件ありで取得するSQLです。
SQLの実行と同時にIOの情報を取得するため、あらかじめ

SET STATISTICS IO ON

のSQLを発行しています。

  • 1つ目のSQL
  • 
    select id, dt from TestTable1 ;
    

    実行プラン1
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2858、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。
  • 2つ目のSQL
  • 
    select id, dt from TestTable1 where dt between cast('2007/01/01' as datetime) and cast('2010/01/01' as datetime);
    

    実行プラン2
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2858、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。


ここで、付加列を持つインデクスを作成します。
id列がキーでdt列が付加列になるように指定します。

CREATE INDEX IX_Test
ON TestTable1 (id)       
INCLUDE (dt)

インデクス作成後、先ほどと同じSQLを再実行して実行プランを見てみます。
  • 1つ目のSQL
  • 
    select id, dt from TestTable1 ;
    

    実行プラン1
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 324、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。
  • 2つ目のSQL
  • 
    select id, dt from TestTable1 where dt between cast('2007/01/01' as datetime) and cast('2010/01/01' as datetime);
    

    実行プラン2
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 324、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。


論理読み取り数やI/Oのコストが減少したのを確認してもらえると思います。
インデクスにキー列(id列)以外に付加列(dt列)を格納するようにしたため、
テストしたSQLはインデクスだけをサーチして結果を返せるようになったため、IOコストが下がったといえます。

こんな感じで便利な付加列ですが、付加列をつけたからと言って早くなるとは限らないです。
例えば、付加列の指定をdt列ではなくvalue列でインデクス作成をしたとします。
その後、2つの付加列に指定したvalue列に対して検索条件をつけたSQLを実行してもテーブルスキャンと大差ない結果が取得されます。
まずは、インデクスのない状態でSQLを発行した結果を取得します。
  • 1つ目のSQL
  • 
    select id, [value] from TestTable1
    

    実行プラン1
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2858、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。
  • 2つ目のSQL
  • 
    select id, r from
    (select id, cast(replace([value],'01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789','') as int) as r from TestTable1 ) t
    where r between 1 and 500 
    

    実行プラン2
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2858、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。

今度はvalue列を付加列に指定して、インデクスの作成を行います。

CREATE INDEX IX_Test
ON TestTable1 (id)       
INCLUDE (value)

その後、再び同じSQLを実行してみます。
  • 1つ目のSQL
  • 
    select id, [value] from TestTable1
    

    実行プラン1
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2825、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。
  • 2つ目のSQL
  • 
    select id, r from
    (select id, cast(replace([value],'01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789','') as int) as r from TestTable1 ) t
    where r between 1 and 500 
    

    実行プラン2
    テーブル 'TestTable1'。スキャン回数 1、論理読み取り数 2825、物理読み取り数 0、先行読み取り数 0、LOB 論理読み取り数 0、LOB 物理読み取り数 0、LOB 先行読み取り数 0。

この様に、付加列の値が大きい場合、インデクスのデータが大きくなってしまうため
論理読み取り数やI/Oのコストが大きく改善されることはなくなってしまいます。

便利な付加列をうまく活用していただけたら幸いです。
 
リハビリで2つの記事を連投してみましたが・・・・
ちょっと文章が変かも~~とか、疲れる~~とかいろいろ大変(^^;
わかりにくかったらごめんなさい。
投稿日時 : 2007年10月11日 14:38

コメント

# re: 付加列インデクスで遊んでみました。 2007/10/11 15:16 ちゃっぴ
( ̄▽ ̄ )ノ☆・゜:*☆【ネ兄】;:*:;゜:*☆ヽ(  ̄▽ ̄)

復活

# re: 付加列インデクスで遊んでみました。 2007/10/11 15:36 夏椰
ありがとぅごさいますぅo(^-^)o

# re: 付加列インデクスで遊んでみました。 2007/10/11 16:09 のん
かやさんの久々のエントリだ(・∀・)♪+.゚



# re: 付加列インデクスで遊んでみました。 2007/10/11 18:47 黒龍
確かに下がってますね。一つ目のクエリでも下がるのはテーブルと比べてインデックスが小さく済むからIOが減るってことかしら??
付加列ってたしか非クラスタ化インデックスのみでしたっけ?
いつも使おうと思ったときにテーブル作り直してた思い出が・・・^^;;

# re: 付加列インデクスで遊んでみました。 2007/10/12 9:24 けろ
復活おめでとうございます!夏椰さんのエントリが見れて、嬉しいです。

さて、上記ですが、項目value のサイズがmax なので、付加列index をつけても、あまり改善されないという言い方が正しいのかもしれませんね。(この例の場合)


# re: 付加列インデクスで遊んでみました。 2007/10/12 12:18 夏椰
>黒龍さん
http://msdn2.microsoft.com/ja-jp/library/ms190806.aspx
を見ると非クラスタ化インデクスだけですね(^^)

>けろさん
「valueのサイズがmax」という表現だと
「maxじゃなければいいのか」ととらえることもできてしまうので、「付加列の値が大きい」って書いてしまいました。
書き直すと「付加列の格納バイト数が大きい場合」って感じですかね。
#max→200ぐらいに制限して確認してみたところ、結果は一緒だったので


# re: 付加列インデクスで遊んでみました。 2007/10/13 13:00 けろ
サイズが、max でも 200 でも変わらなかったんですね。
ということは、値が大きめだと... というのが表現が適切かもしれませんね。

勉強になりました。



# http://burberry.suppa.jp/ 2012/11/06 15:53 バーバリー 財布 メンズ
突然訪問します失礼しました。あなたのブログはとてもすばらしいです、本当に感心しました!

# re: ????????????????? 2021/08/07 3:53 hydroxycloroquine
chrloroquine https://chloroquineorigin.com/# hcqs 200

# MqZmSqumoZCrNktQ 2022/04/19 9:53 johnansaz
http://imrdsoacha.gov.co/silvitra-120mg-qrms

# baxgfvlbeykq 2022/05/31 20:41 vnrinrdy
http://erythromycinn.com/# erythromycin ointment for newborns

Post Feedback

タイトル
名前
Url:
コメント