1

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 行が含まれており、約 1 時間かかります。完了するまでに 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 分以上かかります。

テーブルの更新にかかる時間を短縮する方法についてのアイデアはありますか?

ありがとう。

4

2 に答える 2

1

機能のため、最初の更新は遅いです。彼らは単に何度も実行しています。

2番目のケースでは、チェックサムに時間がかかりすぎる可能性があります。

ヒントを試してみてください。

各一時テーブルにIDENTITY列を配置し、それらにid-sを指定してから、SQLで結合を使用し、外部キーのようなc#のランダム値のみを一時テーブルにスローするソリューションについてどう思いますか。行を使用すると、最初に新しいIDベースのレコードを挿入してから、メインテーブルで1つの大きな更新のみを実行できます。最初はやり過ぎかもしれませんが、それはより良い結果をもたらす可能性があると思います。以前は、テストデータベースの事前入力にこのようなものを使用していました。

PS:タイプミスと読みやすさのために申し訳ありませんがAndroid携帯を使用しました:)

于 2012-08-23T11:49:36.363 に答える
1

私の提案は、複数の関数を複数回呼び出すのではなく、単一のテーブル値関数を作成して、それらのランダム値を含むテーブルを返すことを検討することです。このようなもの:

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

次に、テーブルを返すので、テーブルに参加でき、関数に対して行う複数の呼び出しを最小限に抑えることができます。

于 2012-08-23T11:58:24.040 に答える