C# 是否对导致问题的字符串值进行简洁的参数化查询?
我有下面这个方法1查询,它是使用dapper参数化的,问题是使用这种方法,即使在等待30秒之后,查询也会超时,通常在使用纯sql的SSM上最多需要1秒 然而,方法2查询实际上在查询构建在服务器端而不是参数化查询的情况下工作。我注意到的一件事是,它可能与FirstName和LastName的筛选器有关,我在方法2中对这些筛选器引用了单引号,但对方法1没有引用 方法1有什么问题C# 是否对导致问题的字符串值进行简洁的参数化查询?,c#,sql,sql-server,dapper,C#,Sql,Sql Server,Dapper,我有下面这个方法1查询,它是使用dapper参数化的,问题是使用这种方法,即使在等待30秒之后,查询也会超时,通常在使用纯sql的SSM上最多需要1秒 然而,方法2查询实际上在查询构建在服务器端而不是参数化查询的情况下工作。我注意到的一件事是,它可能与FirstName和LastName的筛选器有关,我在方法2中对这些筛选器引用了单引号,但对方法1没有引用 方法1有什么问题 Method # 1 string query = "SELECT * FROM dbo
Method # 1
string query = "SELECT *
FROM dbo.Customer c
WHERE c.MainCustomerId = @CustomerId
AND (@IgnoreCustomerId = 1 OR c.CustomerID = @FilterCustomerId)
AND (@IgnoreFirstName = 1 OR c.FirstName = @FilterFirstName)
AND (@IgnoreLastName = 1 OR c.LastName = @FilterLastName)
AND (@IgnoreMemberStatus = 1 OR c.CustomerStatusID = @FilterMemberStatus)
AND (@IgnoreMemberType = 1 OR c.CustomerTypeID = @FilterMemberType)
AND (@IgnoreRank = 1 OR c.RankID = @FilterRank)
ORDER BY c.CustomerId
OFFSET @OffSet ROWS
FETCH NEXT 50 ROWS ONLY";
_procExecutor.ExecuteSqlAsync<Report>(query, new
{
CustomerId = customerId,
IgnoreCustomerId = ignoreCustomerId,
FilterCustomerId = filter.CustomerID,
IgnoreFirstName = ignoreFirstName,
FilterFirstName = filter.FirstName,
IgnoreLastName = ignoreLastName,
FilterLastName = filter.LastName,
IgnoreMemberStatus = ignoreMemberStatus,
FilterMemberStatus = Convert.ToInt32(filter.MemberStatus),
IgnoreMemberType = ignoreMemberType,
FilterMemberType = Convert.ToInt32(filter.MemberType),
IgnoreRank = ignoreRank,
FilterRank = Convert.ToInt32(filter.Rank),
OffSet = (page - 1) * 50
});
Method # 2
string queryThatWorks =
"SELECT *
FROM dbo.Customer c
WHERE c.MainCustomerId = @CustomerId
AND ({1} = 1 OR c.CustomerID = {2})
AND ({3} = 1 OR c.FirstName = '{4}')
AND ({5}= 1 OR c.LastName = '{6}')
AND ({7} = 1 OR c.CustomerStatusID = {8})
AND ({9} = 1 OR c.CustomerTypeID = {10})
AND ({11} = 1 OR c.RankID = {12})
ORDER BY c.CustomerId
OFFSET {13} ROWS
FETCH NEXT 50 ROWS ONLY";
_procExecutor.ExecuteSqlAsync<Report>(string.Format(queryThatWorks,
customerId,
ignoreCustomerId,
filter.CustomerID,
ignoreFirstName,
filter.FirstName,
ignoreLastName,
filter.LastName,
ignoreMemberStatus,
Convert.ToInt32(filter.MemberStatus),
ignoreMemberType,
Convert.ToInt32(filter.MemberType),
ignoreRank,
Convert.ToInt32(filter.Rank),
(page - 1) * 50
), null);
我已经看过无数次了 我愿意打赌您的列是varChar,但Dapper正在以nVarChar的形式发送您的参数。发生这种情况时,SQL Server必须对存储在每一行中的值进行转换。除了速度非常慢之外,这还阻止您使用索引
请参见中的Ansi字符串和varchar。您知道如何获取执行计划XML吗?如果是,请张贴。这始终是解决这类问题的第一步。因为一个查询是通过dapper参数化的,另一个是普通sql,我可以得到普通sql的执行计划,但运行速度很快。对于参数化的,我不确定是否可以生成执行计划要获得Dapper的执行计划,请使用SQL Profiler工具。这将捕获发送到数据库的实际SQL。从那里你可以将它粘贴到SSM中,并获得正常的计划。出于好奇,为什么你使用“ignoreColumn”方法而不是简单地测试可空性:@firstName为NULL或c.firstName=@firstName…只会大大减少参数数量。这就是为什么我要创建自己的ORM,Tortuga链。在进行常规查询时,它将自动检测要使用的参数类型。