【问题标题】:Any way to speed up this UPDATE? C#, SQL, T-SQL有什么方法可以加快这个更新? C#、SQL、T-SQL
【发布时间】:2012-08-18 19:07:55
【问题描述】:

SQL:

CREATE FUNCTION dbo.fnRandomForeNames ()
RETURNS VARCHAR(50) 
AS
BEGIN
RETURN  (
            SELECT TOP 1 [FirstName]
            FROM [tmp_ForeNames] 
            ORDER BY (SELECT new_id from GetNewID)
        )
END
GO

dbo.fnRandomSurNames() 等的类似函数

UPDATE Table1
SET firstname = dbo.fnRandomForeNames(),
    lastname = dbo.fnRandomSurNames(),
    address1 = dbo.fnRandomAddress1(),
    address2 = dbo.fnRandomAddress2(),
    address3 = dbo.fnRandomAddress3(),
    birthdate = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '1990-01-01')

我的 C# 代码:

    private void RunThis(string connString, StreamReader sr)
    {
        sr.BaseStream.Position = 0;
        string sqlQuery = sr.ReadToEnd();
        using (SqlConnection connection = new SqlConnection(connString))
        {
            Server server = new Server(new ServerConnection(connection));
            server.ConnectionContext.StatementTimeout = 4200;
            server.ConnectionContext.ExecuteNonQuery(sqlQuery);
        }
        sr.Close();
    }

........

 RunThis(e.Argument.ToString(), _updateClaim);

e.Argument.ToString() 是连接字符串。

CREATE FUNCTION 脚本运行较早,运行时间非常短。 此外,名称存储在 tmp 数据库中,这些名称是通过数组在 C# 中输入的。 这些也需要很少的时间来运行。

Table1 包含大约 140,000 行,大约需要 140,000 行。 14 分钟完成。

我也尝试过使用参数化 SQL 查询,跳过 tmp 表和 SQL 函数,而是创建 SQL 查询并从代码中执行它,如下所示:

UPDATE Table1
SET lastname = '{0}',
    firstname = '{1}',
    birthdate = DATEADD(DAY, ABS(CHECKSUM(NEWID()) % 3650), '1990-01-01'),
    address1 = '{2}',
    address2 = '{3}',
    address3 = '{4}'
    WHERE u_id = '{6}'

还有一些 C#:

 using (SqlConnection connection = new SqlConnection(connString))
        {
            connection.Open();
            for (int i = 0; i < arraySize; ++i)
            {
                string updateString = string.Format(updateString2, GetRandomSurname(), GetRandomForeName(), GetRandomAddress1(), GetRandomAddress2(), GetRandomAddress3(), "", ids[i]);
                SqlCommand cmd = new SqlCommand(updateString, connection);
                cmd.CommandType = CommandType.Text;
                cmd.ExecuteNonQuery();
            }
        }

后一种方法也需要 14 分钟以上。

关于如何减少更新表格所需时间的任何想法?

谢谢。

【问题讨论】:

  • 我建议你把你的代码放在codereview.stackexchange.com
  • 他们的索引是否在表的列上?
  • 什么是使用ServerConnection的Server,我的意思是第3方代码,你也需要用using语句包装它
  • @rshetye 不,没有索引
  • @HatSoft Server 是 Microsoft.SQLServer.Management.SMO 中的一个类 msdn.microsoft.com/en-us/library/…

标签: c# sql winforms tsql


【解决方案1】:

第一次更新很慢,因为功能。他们只是运行了太多次。

在第二种情况下,校验和可能需要很长时间。

只是一个提示,你可以试试:

您如何看待在每个临时表上放置一个 IDENTITY 列的解决方案,只需给它们 id-s,然后只需要在 sql 中使用连接,并且只在 c# 中抛出一些随机值,如外键到临时表。使用这些行,您可以首先插入新的基于 id 的记录,然后在主表上只运行一次大更新。首先可能是矫枉过正,但我​​认为它可以取得更好的结果。过去我们使用类似的东西来预填充一些测试数据库。

P.S.:抱歉,由于打字错误和可读性,我使用了 android 手机:)

【讨论】:

    【解决方案2】:

    我的建议是查看创建一个 table valued function 以返回包含这些随机值的表,而不是多次调用多个函数。像这样的:

    create function dbo.fnRandomStuff
    (
      @FirstName bit, 
      @LastName bit, 
      @address1 bit,
      @address2 bit,
      @address3 bit
    )
    RETURNS @RandomStuff TABLE 
    (
        FirstName varchar(50) NULL, 
        LastName varchar(50) NULL, 
        address1 varchar(50) NULL, 
        address2 varchar(50) NULL, 
        address3 varchar(50) NULL
    )
    AS
    BEGIN
      -- your code here to get the random stuff based on the 
      -- parameters passed
    
    END
    

    然后,由于您要返回一个表,您可以加入该表,它将最大限度地减少您对函数进行的多次调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 1970-01-01
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多