2016-11-22 36 views
1

我有一个问题,在一个超过200.000条记录的桌子上执行过程很慢。C#executioncalar真的很慢在大桌子上

如果表中存在的VARCHAR,并返回一个计数,看看是否有任何可以找到我使用的检查方法:

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; 
    } 
} 

我的表是建立这样的:

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

是有没有办法让我的C#方法更快,还是我需要改变我的表中的东西?

+1

尝试在桌子上 – Praveen

+0

这并不是说你的方法是缓慢增加的网址列的索引。这是你的问题需要很长时间。您可以在'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个字符,然后改为索引该列。然后,你可以这样做:

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

,那么你还需要添加@shortenedUrl参数(当然),它应该包含你正在寻找网址的前50个字符。

+0

谢谢,这真的有助于提高性能。 –

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