SQL Server中的查询运行速度比通过发送的ADO.NET命令快

时间:2012-11-08 05:12:29

标签: c# tsql ado.net database-performance

所以我在我的DL中的CRUD方法中有以下内容,它带回了一个照片blob:

    public static MemberPhoto RetrievePhoto(string customerID)
    {
        Database db = DatabaseFactory.CreateDatabase(Config.DbConnectionString);

        using (DbCommand cmd = db.GetSqlStringCommand(string.Format(@" SELECT  customerID,
                                                                                p.Photo as PhotoBlob

                                                                         FROM 
                                                                         SomeTable t

                                                                         WHERE 
                                                                         t.PhotoID = (SELECT MAX(t.PhotoID) FROM SomeTable t
                                                                                      WHERE t.customerID = @{0} 
                                                                                      GROUP BY t.CustomerID)", "customerID")))
        {
            try
            {
                db.AddInParameter(cmd, "@customerID", DbType.String, customerID);

                using (IDataReader reader = db.ExecuteReader(cmd))
                {
                    if (reader.Read())
                    {
                        Photo photo = new Photo();
                        photo.LoadFromDataReader(reader);
                        return photo;
                    }
                }
            }

所以比我从管理工作室直接运行要快10秒;

SELECT  customerID,
    t.Photo as PhotoBlob

    FROM 
    SomeTable t

    WHERE 
    t.PhotoID = (SELECT MAX(t.PhotoID) FROM SomeTable t
              WHERE t.customerID = '0000900595555' 
              GROUP BY t.CustomerID)

我不知道是不是因为读者需要一段时间才能阅读blob并将其带回来或者是什么?如果这就是问题,你如何加快速度呢?它在数据库的瞬间,我运行该查询,这是一个毫秒的结果时间。

更新:

更多信息;表中的字段类型是该BLOB的SQL Sever中的类型。

我也运行了我的单元测试,相同的时间,即使它遇到了我的LoadFromReader:

[Test]
public void GetMemberPhoto_ByContractNumber_ReturnsAValidMemberPhoto()
{
    // Arrange
    const string customerID = "0044664176";

    // Act
    DTO.MemberPhoto memberPhoto = MemberPhotoCRUD.RetrieveMemberPhotoFromBlob(customerID);

    //Assert
    Assert.IsNotNull(memberPhoto);
    Assert.IsTrue(memberPhoto.CustomerID > 0);
    Assert.IsNotNull(memberPhoto.PhotoBinary.Length > 0);
}

2 个答案:

答案 0 :(得分:1)

选择错误。不要使用string.Format并将WHERE t.customerID = @{0}更改为WHERE t.customerID = @customerID

现在注释掉photo.LoadFromDataReader(reader);并运行测试。如果时间接近管理工作室,则问题出在LoadFromDataReader方法中。

答案 1 :(得分:1)

您正在返回图像的斑点。 SSMS实际上并未获取所有数据 - 它会截断[n][text][n][varchar](max)imagevarbinary(max)的大值,因为您通常不会直接使用这些结果。听起来这是一个带宽问题。检查blob的大小 - 如果它非常大,这很可能。

异常表现的其他可能性:

  • 不同的隔离级别
  • 不同的SET选项
  • 参数嗅探

此外 - 关于string.Format的评论是正确的;它不会对你造成任何伤害,但它也没有任何有用的目的。就个人而言,我只是直接在查询中写@customerID。否则就像string.Format("this and {0}", "that")一样 - 您也可以使用"this and that"

也可能是在客户端处理图像的速度很慢。为了进行直接比较,您需要将数据作为(例如)byte[]来获取。您的SSMS比较不会将数据处理为Photo对象。可能是这个是缓慢的操作,所以我会描述photo.LoadFromDataReader(reader)