SQL Database を使って、データベースのアクセススピードの速度比較をしてみた
これも個人レベルの気になったことがあったので、ちょっと実験してみます。データベースへのアクセス速度比較です。内容としては、今更こんなことと思われるレベルなのですが.... 仮想環境上の SQL Server で検証するのも何となくつまらないので、Microsoft Azure、まだ Windows Azure の SQL Database を使用して検証してみます。
Windows Azure のポータルより、SQL データベースを選択し、SQL データベースを作成します、をクリックします。
設定を行い、赤枠の部分をクリックします。
ログイン名およびパスワードをリージョンを設定し、赤枠部分をクリックします。
以上でデータベースの作成は完了です。あとは、下記の内容に従って準備をします。
早速、データベースを参照してみましょう。ログイン画面は Silverlight なんですね。もう懐かしい感じになってしまっていますが....ID, パスワードを入力し、Log On をクリックします。
管理ポータルはそんなに使いやすいものではないですね。SQL Server Management Studio から接続してみましょう。 SQL Server 2014 CTP2 の環境から接続してみます。
赤枠部分のアドレスを SQL Server Management Studio のサーバ名に設定し、 ログインします。
サーバに接続が成功すると、下記のように表示されます。下部に 今回接続した SQL データベースが表示されています。
AdventureWorks2012 データベースをごっそり、SQL データベースに移行したいと思います。容量的には問題なさそうですね。では移行してみたいと思います。
赤枠のメニューをクリックします。
SQL データベースに接続し、赤枠の Next をクリックします。
赤枠の Finish をクリックします。
おおっと、SQL Server 2014 はまだ対応されていないんですね。環境を 2012 に変えてみましょう。( 事前に調べずにやってしまうのが、私のいけないところです.... )
ん?2012 にしてもダメですね。あー、そのまま移行ができないんですね。スクリプトを生成しても、そのままは使えないんですね。冷静に考えると当たり前ですね。何使えばいいんでしょうか? BCP コマンドですかね?試してみましょう。
再度手順を整理して、説明します。(前に示した手順は意味なしです...)
- SQL データベース側のレイアウトを作成します。
主キーは必ず指定してください。インポート時に失敗します。 -
bcp コマンドを実行するのに必要なフォーマットファイルを出力します。下記のコマンドを実行します。
bcp AdventureWorks2012.Sales.SalesOrderDetail format nul -c -f SalesOrderDetail.fmt -T
- bcp コマンドでも、エクスポートのどちらでもよいので、タブ区切りでデータを抽出します。
- データを SQL データベースにインポートするため、下記のコマンドを実行します。
以上の手順で、SQL Server 2012 → SQL Database のデータ移行が可能です。きちんとデータが移行されたかを確認してみましょう。管理ポータルから、SQL を発行するとデータがきちんと格納されていることがわかります。
今後何かしら改善されていくとは思いますが、SQL データベース への移行は面倒ですね。それでは、検証を行うためのサンプルソースです。( 適当なソースですいません。 )
using System;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Windows.Forms;
namespace DataSetAndDataReader
{
public partial class Form1 : Form
{
string sqlStr = "select * from Sales.SalesOrderDetail Where SalesOrderID = 75121;" +
"select * FROM Sales.SalesOrderHeaderSalesReason Where SalesOrderID = 75121";
string connectStr = "Server=tcp:servername.database.windows.net,1433;Database=AdventureWorks;" +
"User ID=userid@servername;Password=password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;";
public Form1()
{
InitializeComponent();
}
private void DataSet_Click(object sender, EventArgs e)
{
var sw = new Stopwatch();
sw.Start();
using (var cn = new SqlConnection())
{
cn.ConnectionString = connectStr;
cn.Open();
var da = new SqlDataAdapter(sqlStr, cn);
var ds = new DataSet("Sales");
da.Fill(ds, "SalesOrderDetail");
da.Fill(ds, "SalesOrderHeader");
var dt1 = ds.Tables["SalesOrderDetail"];
var dt2 = ds.Tables["SalesOrderHeader"];
//SalesOrderDetail
foreach (DataRow dr1 in dt1.Rows)
{
//何かの処理を書く予定。
}
//SalesOrderHeader
foreach (DataRow dr2 in dt2.Rows)
{
//何かの処理を書く予定。
}
}
sw.Stop();
MessageBox.Show(sw.Elapsed.ToString());
}
private void DataReader_Click(object sender, EventArgs e)
{
var sw = new Stopwatch();
sw.Start();
using (var cn = new SqlConnection())
{
cn.ConnectionString = connectStr;
cn.Open();
var cmd = new SqlCommand();
cmd.CommandText = sqlStr;
cmd.Connection = cn;
var dr = cmd.ExecuteReader();
while (dr.Read())
{
//何かの処理を書く予定。
}
//次の結果を見る。
dr.NextResult();
while (dr.Read())
{
//何かの処理を書く予定。
}
dr.Close();
cn.Close();
}
sw.Stop();
MessageBox.Show(sw.Elapsed.ToString());
}
}
}
上記のプログラムで計測すると、おおよそ ExecuteReader のほうが約2倍高速でした。ただ、この事実が知りたかっただけなんですが、結構大げさな記事になってしまいました。