C#executioncalar在大桌子上真的很慢

时间:2016-11-22 09:42:40

标签: c# sql-server sqlcommand executescalar

我遇到的问题是,在具有超过200,000条记录的表格上,执行标记真的很慢。

我使用的方法检查表中是否存在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#方法更快,还是我需要更改表格中的内容?

5 个答案:

答案 0 :(得分:1)

数据库中的缓慢,正如其他人已经指出的那样。由于您实际上并不需要精确计数,而是指示行是否存在的布尔值,因此可能会略微提高性能:

SELECT TOP 1 1 from PriorityQueue where absolute_url = @url

使用此查询,数据库可以在找到第一个(也可能是唯一的)匹配后停止搜索。

但要获得显着的性能提升,您需要在absolute_url列中添加索引。但是该列目前被定义为varchar(900),这是(如果我已经正确搜索),在列可以在索引中的时间限制。如果对其进行索引,索引将占用与表本身大致相同的空间量。

如果可能,请缩短列,然后在其上添加索引。如果你绝对不能缩短它,你可以添加一个包含列的第一个(例如)50个字符的列,然后将该列编入索引。然后你可以这样做:

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

然后你还需要添加@shortenedUrl参数,该参数应该(当然)包含你要查找的网址的前50个字符。

答案 1 :(得分:0)

ExecuteScalar()仅用于运行查询,提取数据的时间更长,需要花费更多时间。

答案 2 :(得分: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 

答案 3 :(得分:0)

SQL Count总是很慢,有大量记录。请寻找其他选择。您可以根据您的要求使用“存在”或任何其他选项。

以下是一些可以帮助您理解的链接。

SQL Server Count is slow

SQL count(*) performance

SQL Server - Speed up count on large table

答案 4 :(得分:0)

20,000行选择总是稍微慢一点,查看索引并在后台工作程序中执行AlreadyQueued可能是个好主意。

  

https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx