2012-01-17 12 views
3

DataTableの間でループするforが速くなるか、SQL Serverでこの操作を実行するかどうかを確認します。だから、私はこのような表を作成:SQL ServerとC#の間のパフォーマンスの問題

CREATE TABLE [dbo].[tbl_Test_Data](
[Id] [int] IDENTITY(1,1) NOT NULL, 
[Name] [nvarchar](50) NOT NULL, 
[LName] [nvarchar](50) NOT NULL, 
[f_date] [datetime] NOT NULL, 
[flag] [bit] NOT NULL, 
[Age] [int] NOT NULL, 
[amount] [decimal](23, 5) NOT NULL, 
    CONSTRAINT [PK_tbl_Test_Data] PRIMARY KEY CLUSTERED ([Id] ASC) 

をし、私はAge列に索引を作成します。

CREATE NONCLUSTERED INDEX [idx_age] ON [dbo].[tbl_Test_Data] 
(
[Age] ASC 
) 
INCLUDE ([Id], [f_date]) 

とテストデータの100000行挿入します。次に

DECLARE @a INT 
SET @a = 100000; 

WHILE @a >= 0 
BEGIN 
DECLARE @d DATETIME ; 
SET @d = DATEADD(d,CAST(RAND() * 100 AS INT),GETDATE()); 

DECLARE @b BIT; 
IF @a % 2 =0 
    SET @b=0; 
ELSE 
    SET @b=1; 

    INSERT INTO tbl_Test_data 
    VALUES(N'nima', 
      N'agha', 
      DATEADD(d,CAST(RAND() * 100 AS INT),GETDATE()), 
      @b, 
      CAST(RAND() * 100 AS INT), 
      CAST(RAND() AS DECIMAL(23,5))) 

SET @[email protected] -1; 
END 

を私は2つのボタンでC#のWindowsアプリケーションを作成します。 SQLクエリからの更新のために私はこのコードを書く:

private void button2_Click(object sender, EventArgs e) 
{ 
    Stopwatch sq = new Stopwatch(); 
    sq.Start(); 

    using (SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=Northwind;Integrated Security=True")) 
    { 
     using (SqlCommand cmd = new SqlCommand()) 
     { 
      string txt = "UPDATE tbl_Test_Data SET f_date=getdate() WHERE Age>80;"; 
      txt += "SELECT Id,Name,LName,f_date,flag,Age,amount FROM [Northwind].[dbo].[tbl_Test_Data]"; 
      cmd.CommandText = txt; 
      cmd.CommandType = CommandType.Text; 
      cmd.Connection = cn; 

      using (SqlDataAdapter da = new SqlDataAdapter()) 
      { 
       da.SelectCommand = cmd; 
       DataTable dt = new DataTable(); 
       cn.Open(); 
       da.Fill(dt); 
       cn.Close(); 

       dataGridView2.DataSource = dt; 
      } 
     } 
    } 
    sq.Stop(); 
    label2.Text = sq.Elapsed.TotalMilliseconds.ToString(); 
} 

をしてforループを使用するために、私は、この書き込み:

Stopwatch sq = new Stopwatch(); 
sq.Start(); 
using (SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=Northwind;Integrated Security=True")) 
{ 
    using (SqlCommand cmd = new SqlCommand()) 
    { 
     cmd.CommandText = "SELECT Id,Name,LName,f_date,flag,Age,amount FROM [Northwind].[dbo].[tbl_Test_Data]"; 
     cmd.CommandType = CommandType.Text; 
     cmd.Connection = cn; 

     using (SqlDataAdapter da = new SqlDataAdapter()) 
     { 
      da.SelectCommand = cmd; 
      DataTable dt = new DataTable(); 
      cn.Open(); 
      da.Fill(dt); 
      cn.Close(); 

      for (int i = 0; i < dt.Rows.Count; i++) 
      { 
      if (int.Parse(dt.Rows[i]["Age"].ToString()) > 80) 
      { 
       dt.Rows[i]["f_date"] = DateTime.Now; 
      } 
      else 
      { 
       dt.Rows[i]["f_date"] = DateTime.Now.AddDays(-100); 
      } 
      } 

      dataGridView1.DataSource = dt; 
     } 
    } 
} 
sq.Stop(); 
label1.Text = sq.Elapsed.TotalMilliseconds.ToString(); 

をしかし、私は、私はforループを使用する場合は、SQL Serverのより短い時間を要することに驚く参照します。約(50%)。私はそれを数回試します。

アップデートを使用するのに時間がかかります。

答えて

4

UPDATEは、実際にはサーバーレベルでロックとディスクアクセスを処理しなければならず、基本テーブルのインデックスも更新する必要があります。

forループは、このオーバーヘッドのいずれかを処理する必要はありません。ただし、ループ内の変更は、アプリケーション以外では表示されません。

UPDATEは、そのテーブルに対する他のすべてのクエリの変更を行います。 forループの変更は、アプリケーションテーブル内のデータテーブルでのみ表示されます。

これらのクエリを掲載順に実行した場合、最初のクエリがディスクからページを取得するためのIOコストを支払って、2回目の実行でキャッシュされたデータを取得できた可能性もありますメモリからのページ。

1

実際にはの場合はでサーバー上のデータを変更しないため、アプリケーションにデータをロードして変更します。

更新ケースは、まずサーバー上のデータを変更し、アプリケーションに読み込みます。明らかに時間がかかります

関連する問題