SQL Server和C#之间的性能问题
本文关键字:性能 问题 之间 Server SQL | 更新日期: 2023-09-27 18:20:29
我想检查在DataTable
之间循环的for
是否更快,或者在SQL Server中执行此操作。所以,我创建了一个这样的表:
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 @a=@a -1;
END
然后我创建了一个带有两个按钮的C#窗口应用程序。对于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%)。我测试了好几次。
为什么使用for比使用更新花费更短的时间?
UPDATE
实际上必须在服务器级别处理锁和磁盘访问,而且它还必须更新基表上的索引。
for
循环不必处理任何这些开销。但是,除了应用程序之外,for
循环中所做的更改对其他任何东西都不可见。
UPDATE
将对该表的所有其他查询进行更改。for
循环更改仅在具有数据表的应用程序范围内可见。
顺便说一句,如果您按照这些查询的发布顺序运行这些查询,那么第一个查询就支付了从磁盘检索页面的IO成本,而第二个运行则能够从内存中提取缓存的页面。
因为在实际情况下,您不会用for的情况更改服务器上的数据,所以您可以将数据加载到应用程序中并在那里进行更改。
更新案例首先更改服务器上的数据,然后将其加载到应用程序中。显然需要更多的时间