SQL Server Compact コネクション確立パフォーマンス
クライアントアプリケーションでSQL Server Compact(4.0)を利用しています。
コネクションの確立が結構重い処理だという雰囲気があったので、調べてみました。
using System; using System.Data.SqlServerCe; using System.Diagnostics; using System.IO; namespace SqlCeConnectionPerformance { /// <summary> /// SqlCeConnectionのConnection.Openがコストが高い処理であることを検証するプログラム /// </summary> class Program { static void Main(string[] args) { // 準備(ファイル作成、DDL、データ登録) const int TEST_COUNT = 1000; const string SDF_PATH = @".\Test.sdf"; File.Delete(SDF_PATH); var connectionString = string.Format(@"Data Source={0}", SDF_PATH); using (var engine = new SqlCeEngine(connectionString)) engine.CreateDatabase(); var ddlConnection = new SqlCeConnection(connectionString); var ddlCommand = ddlConnection.CreateCommand(); ddlCommand.CommandText = @" CREATE TABLE Hoge( Id int IDENTITY (0,1) PRIMARY KEY, Name nvarchar(20) NOT NULL )"; using (ddlConnection) { ddlConnection.Open(); ddlCommand.ExecuteNonQuery(); } var insertConnection = new SqlCeConnection(connectionString); var insertCommand = insertConnection.CreateCommand(); using (insertConnection) { insertConnection.Open(); for (int i = 0; i < TEST_COUNT; i++) { insertCommand.CommandText = string.Format(@"INSERT INTO Hoge(Name) VALUES('{0}')", i); insertCommand.ExecuteNonQuery(); } } // 検証 -> Openは一回 var select0Connection = new SqlCeConnection(connectionString); var select0Command = select0Connection.CreateCommand(); var watch0 = Stopwatch.StartNew(); using (select0Connection) { select0Connection.Open(); for (int i = 0; i < TEST_COUNT; i++) { select0Command.CommandText = string.Format(@"SELECT * FROM Hoge WHERE Id = {0}", i); var obj = select0Command.ExecuteScalar(); } } Console.WriteLine(watch0.ElapsedMilliseconds); // 3回実行平均値 : 275ms // 検証 -> 毎回Open var watch1 = Stopwatch.StartNew(); for (int i = 0; i < TEST_COUNT; i++) { var select1Connection = new SqlCeConnection(connectionString); var select1Command = select1Connection.CreateCommand(); using (select1Connection) { select1Connection.Open(); select1Command.CommandText = string.Format(@"SELECT * FROM Hoge WHERE Id = {0}", i); var obj = select1Command.ExecuteScalar(); } } Console.WriteLine(watch1.ElapsedMilliseconds); // 3回実行平均値 : 16845ms } } }
歴然とした差があります。UIでのインタラクション処理(データ作成->保存など)で毎回Open処理が行われるのはまずいですね。
コネクションを開きっぱなしにする方向で考えてみます。この辺り、サーバーサイドのノウハウとは異なるところだと思います。