2012-08-23 87 views
1

SQL:任何方式來加快此更新? C#,SQL,T-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#中。 這些也需要很少的時間來運行。

表1包含大約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分鐘以上。

有關如何縮短更新表所需時間的想法?

謝謝。

+0

我建議你把你的代碼放在http://codereview.stackexchange.com/ – HatSoft

+0

是他們在表的列上的任何索引? – rshetye

+0

什麼是ServerConnection的服務器,我的意思是第三方代碼,也需要使用語句 – HatSoft

回答

1

由於功能,第一次更新很慢。他們只是跑了太多次。

在第二種情況下,校驗和可能花費太多時間。

只是一個提示可能你可以嘗試:

你想想,你把一個IDENTITY列的各臨時表的解決方案是什麼,只是給他們的ID-S,然後只需要使用在加入sql,並且只在c#中像引用臨時表中的外鍵一樣引入一些隨機值。通過這些行,你可以先插入新的基於id的記錄,然後在主表上只運行一個大的更新。首先可能是過度殺傷力,但我認爲它可以取得更好的結果。在過去,我們使用這樣的方式來預填一些測試數據庫。

PS:我用的Android手機,因爲錯別字和可讀性:)的遺憾

1

我的建議是在外觀創建一個單一的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 

然後因爲你正在返回一個表,你可以加入在桌子上,它會是你正在爲你的函數多次調用最小化。

相關問題