Archive for the ‘VB.NET’ Category

1月
20

flashcast:フリーで働くITエンジニア集団のブログ: VB.NETの技術メモ~DBアクセスの高速化(バインド変数の使用)前編~では、DBアクセス時に動的にSQLを生成したケースと、バインド変数を使用してSQLを生成したケースを紹介しました。
本編では、計測結果を比較・検証したいと思います。

先ずは、動的にSQLを生成したケースの結果(処理時間)は以下の通りでした。
交互にそれぞれ3回同じ処理を行いました。
●1回目(動的にSQLを生成したケース)

2010/01/19 21:09:13
2010/01/19 21:09:22:700000

●1回目(バインド変数を使用してSQLを生成したケース)

2010/01/19 21:09:34
2010/01/19 21:09:42:700000

●2回目(動的にSQLを生成したケース)

2010/01/19 21:10:23
2010/01/19 21:10:32:700000

●2回目(バインド変数を使用してSQLを生成したケース)

2010/01/19 21:10:34
2010/01/19 21:10:41:700000

●3回目(動的にSQLを生成したケース)

2010/01/19 21:11:11
2010/01/19 21:11:20:700000

●3回目(バインド変数を使用してSQLを生成したケース)

2010/01/19 21:11:45
2010/01/19 21:11:52:700000

※2行目の700000という数字は、DBから郵便番号(7桁)が10万回読み込めた事を証明しています。

動的にSQLを生成したケースは平均9秒、バインド変数を使用してSQLを生成したケースは平均7.3秒。
う~ん微妙な感じ。。。
数件の処理でこの違いであれば、かなりの改善ということになりますが 、10万件の処理でこの結果ということは、今回のテストケース自体が簡単過ぎたからでしょうか?
もう少し複雑な処理や、数百万件という大量のデータを扱う様なケースであれば、更なるパフォーマンス向上が見込めるのかも知れません。
逆に言えばこの様な単純な処理でも、結果にここまで差が出た事は、それなりにパフォーマンス向上の効果が出たと言えるのではないでしょうか?

1月
20

アプリケーションのパフォーマンスでボトルネックになりやすい要因の一つに、データベース(DB)へのアクセスがあります。
今回はDBへのアクセス(特にSQL文の発行)に関して、バインド変数を使ったパフォーマンス向上の方法を紹介し、それぞれの方法でどれだけパフォーマンスに違いが出るのかを検証してみたいと思います。
なお、前提事項として、以下の開発環境で検証をしました。
・言語:VB.NET
・フレームワーク:.NET Framework 2.0
・DBサーバ:SQL Server 2005 Express Edition

検証を行なうに当たり大量のデータが必要なので、zpnaviでもお世話になっている、郵便番号検索 – 日本郵便より提供されている住所データを使用します。
10万件の住所データに対して、1から順番にシーケンス番号を振ります。 そのデータを1件づつ読み込んで、10万件目が終わるまでの処理時間を計測します。

●動的にSQLを生成したケース
動的にSQLを生成したケースでは、以下の様に動的にSQL文を組み立てて、その内容に対してDBにSQLを発行します。

Imports System.Data.SqlClient
Imports System.Text

sub Test()
        Debug.Print(Now)

        Dim SqlConn As New SqlConnection
        Dim SqlCmd As SqlCommand
        Dim SqlRd As SqlDataReader
        Dim StSQL As String
        Dim i As Long
        Dim TownName As New StringBuilder

        SqlConn.ConnectionString = "(DB接続文字列)"
        SqlConn.Open()
        SqlCmd = SqlConn.CreateCommand

        For i = 1 To 100000
            StSQL = "SELECT NEW_ZIP FROM T_ADDRESS WHERE SEQ = " & i
            SqlCmd.CommandText = StSQL
            SqlRd = SqlCmd.ExecuteReader
            SqlRd.Read()
            TownName.Append(SqlRd(0).ToString)
            SqlRd.Close()
        Next
        SqlCmd.Dispose()
        SqlConn.Close()
        Debug.Print(Now & ":" & TownName.Length)

End Sub

●バインド変数を使用してSQLを生成したケース

Imports System.Data.SqlClient
Imports System.Text
sub Test()
        Debug.Print(Now)

        Dim SqlConn As New SqlConnection
        Dim SqlCmd As SqlCommand
        Dim SqlPrm As SqlParameter
        Dim SqlRd As SqlDataReader
        Dim StSQL As String
        Dim i As Long
        Dim TownName As New StringBuilder

        SqlConn.ConnectionString = "(DB接続文字列)"
        SqlConn.Open()
        SqlCmd = SqlConn.CreateCommand
        SqlPrm = SqlCmd.Parameters.Add("@SEQ", SqlDbType.Int)
        SqlPrm.Direction = ParameterDirection.Input
        StSQL = "SELECT NEW_ZIP FROM T_ADDRESS WHERE SEQ = @SEQ"
        SqlCmd.CommandText = StSQL

        For i = 1 To 100000
            SqlPrm.Value = i
            SqlRd = SqlCmd.ExecuteReader
            SqlRd.Read()
            TownName.Append(SqlRd(0).ToString)
            SqlRd.Close()
        Next
        SqlCmd.Dispose()
        SqlConn.Close()
        Debug.Print(Now & ":" & TownName.Length)
End Sub

なお、上記のプログラムを作成するに当たり、.NET アプリケーションのパフォーマンスとスケーラビリティの向上 – 第 12 章 「ADO.NET パフォーマンスの向上」を参考にしました。

前者と後者のプログラムの違いは、各プログラムの19行目のDBに発行するSQL文が動的か、固定かの違いです。

この様な実装方法にする理由はmsdnのサイトには記載されていませんでしたが、Oracleの場合でもバインド変数を使った実装の方が、パフォーマンスがいいと言われています。
具体的な理由もありました。

Oracle Database 10gがOracle Database 10gがSQL文を受け取った場合、共有プール(メモリ領域)をチェックして、文がすでに存在しメモリに格納されているかどうかを確認します。文がメモリに存在し、Oracle Database 10gがその文を再利用できる場合、データベースは文を解析および最適化するタスクをスキップできます。バインド変数を使用すると、SQL文がメモリに格納される可能性が大幅に高まります。これによって、そのSQL文を必要とする次の操作で迅速にそのSQL 文を使用できます。
※Oralceでバインド変数を使用する為には、「Oracle.DataAccess」コンポーネントを参照追加する必要があります。

上記の内容は、値のバインドの「バインド変数が重要な理由」より抜粋

SQL Serverの場合は上記の様な具体的な理由までは記述されていませんでしたが、恐らく同様の理由だと思います。

では動的にSQLを生成したケースと、バインド変数を使用してSQLを生成したケースとではどれくらいパフォーマンスに違いが出るのか?
結果は後日報告したいと思います!

  • Search:
  • flashcastとは?

    東京を中心に、現在フリーランスとして活動しているITエンジニア、および、かつてフリーランスとして活動していた起業家達が立ち上げたコミュニティーです。

    みんなで集まって面白いことをやろう!形に残そう!ということで、ブログをはじめました。

    技術情報や、フリーエンジニアに役立つ情報などを、ご紹介できたらと思っています。

    お問い合わせ:
    info@flashcast.jp
  • カレンダー

    2010年7月
    日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日
    « 6月    
     123
    45678910
    11121314151617
    18192021222324
    25262728293031
  • メンバー紹介

    もじゃもじゃ
    flashcastのリーダー

    3年ほどフリーのITエンジニアとして活動。現在は、社員2名の株式会社を経営しています。

    一攫千金を夢見る野心家です。

    ライブキャスト

    yasu
    ダイバー

    自宅サーバーでホームページを作り始めました。

    少しずつ記事を増やしていきますので足を運んでください。

    よろしくお願いします。

    sa-sa-ki.jp

    のら
    たびびと

    ねこ好きに悪人はいなーいっ!!

    バイクや車も好きです。

    めぐ
    デザイナーのたまご

    音楽とデザインとお酒をこよなく愛する永遠のダイエッター。

    現在ペンタブレットでイラストを勉強中。

    Hiro
    コンサル

    PMやSEの案件を業務委託で請けることが多いですが、小規模案件も受託でやっています。

    得意な分野はマイクロソフト製品や関連技術によるシステム構築です。

    KEI
    取締役の風格

    最年少なのに、メンバーで1番の貫禄の持ち主!?

    C#や.netなどサーバ側の開発が得意。

    ろっきー
    美食家★パパ

    自分にとっての息抜きは、ドライブして温泉に入って、美味しいご飯を食べる事。

    ココロとカラダのリフレッシュを大切にし、日々の仕事に励む一児の父親です。

    郵便番号検索

    my-hobby

    とのさま
    げーむのおうさま

    大人なのに好きなことしかやらない駄目人間。

    Web系が得意、アクセスは苦手><

    tonosamart.com

    セクレタリアト
    ギャンブラー

    フリーランス時代は仲間の現場を探すことが多く、それをきっかけに会社を設立。

    現在はSI業に特化せず、他の業種にも興味を持ち始めています。

    メドレー株式会社

  • 広告