2016-11-22 109 views
1

私はexecutecalarが200.000以上のレコードを持つテーブルで実際には遅いという問題があります。C#executecalar本当に大きなテーブルで遅い

varchar型がテーブルに存在し、何を見つけることができるかどうかを確認するために、カウントを返す場合、私はチェックを使用する方法:

CREATE TABLE PriorityQueue 
(
    queueID int IDENTITY(1,1) PRIMARY KEY, 
    absolute_url varchar (900), 
    depth int, 
    priorty int 
); 

は、次のとおりです。

public static bool AlreadyQueued(string url) 
{ 
    using (SqlConnection connection = new SqlConnection(_connectionString)) 
    { 
     SqlCommand cmd = new SqlCommand("SELECT Count(queueID) from PriorityQueue where absolute_url = @url") 
     { 
      Connection = connection, 
      CommandType = CommandType.Text 
     }; 
     cmd.Parameters.AddWithValue("@url", url); 
     connection.Open(); 
     var count = (int)cmd.ExecuteScalar(); 
     return count > 0; 
    } 
} 

私のテーブルは、このように構築され私のC#メソッドをもっと速くするために、あるいはテーブルの中の何かを変更する必要があるのでしょうか?

+1

それはあなたの方法が遅いということはありませんテーブル – Praveen

+0

にURL列に索引を追加してみてください。あなたの質問は長い時間がかかります。 'absolute_url'にインデックスを追加してビットを速くすることはできますが、大きなテーブルの場合は、それが想定どおりに時間がかかります。 –

+0

また、このクエリをさまざまなURLで再利用する場合は、Addメソッドを使用してパラメータを定義する方がよいでしょう。 Addメソッドを使用すると、パラメーターのタイプとサイズを指定できます。特に、Sizeプロパティ(= 100)を使用すると、データベースエンジンオプティマイザがクエリプランを再利用し、データベース側の処理を高速化できます。 – Steve

答えて

1

既に他者によって指摘されているように遅は、データベース内にあります。あなたが本当に正確な数を必要としないが、むしろブール行が存在するか否かを示すので、あなたがこのようなわずかな性能向上ことがあります。

SELECT TOP 1 1 from PriorityQueue where absolute_url = @url 

このクエリでは、データベースは、一度検索を停止することができます最初の(おそらく唯一の)一致が見つかります。

しかし、パフォーマンスを大幅に向上させるには、absolute_url列にインデックスを追加する必要があります。しかし、現在その列はvarchar(900)と定義されています。これは(もし私が正しくGoogle検索していれば)列が索引にどれくらいの時間を置くことができるかの限度です。そのように索引付けすると、索引は表自体とほぼ同じ量の領域を占有します。

可能であれば、列を短くしてインデックスを追加します。絶対に短縮できない場合は、列の最初の50文字を保持する列を1つ追加し、代わりにその列にインデックスを付けることができます。そして、あなたは次のように行うことができます。

SELECT TOP 1 1 from PriorityQueue where absolute_url = @url and shortened_url = @shortenedUrl 

が次にあなたも(もちろん)あなたが探しているURLの最初の50の文字が含まれている必要があり @shortenedUrlパラメータを追加する必要があります。

+0

これは本当にperfomanceを増やすのに役立ってくれてありがとう。 –

0

ExecuteScalar()はクエリの実行にのみ使用され、取得するデータはそれ以上の時間がかかります。

0

代わりに"SELECT TOP 1 queueID from PriorityQueue where absolute_url = @url"を試しましたか?パフォーマンスが大幅に向上するはずです。いずれの場合においても

、私はあなたがこのようにそれをテストすることができ、あなたが

Create PROCEDURE UrlFound @absolute_url varchar(900) 
AS 
IF (EXISTS(SELECT TOP 1 1 from PriorityQueue where absolute_url = @absolute_url)) 
    RETURN 1 
ELSE 
    RETURN 0; 
GO 

を望むブール値を返すために、データベースにストアドプロシージャを追加提案:

DECLARE @result bit 
exec @result = UrlFound 'YourAbsoluteUrl' 
print @result 
関連する問題