[英]Dapper parameterized query for string value causing issues?
I have this Method# 1 query below that is parameterized using dapper, problem is the query times out with this approach even after waiting 30sec and normally it takes max of 1 sec on SSMS with plain sql. 我在下面使用dapper进行参数化的方法#1查询,问题是即使在等待30秒后查询也会超时,并且通常在使用普通sql的SSMS上最多需要1秒。
However Method # 2 query actually works where the query is built on the server side instead of parameterized one. 但是,方法#2查询实际上可以在服务器端而不是参数化查询的情况下构建查询。 One thing i have noticed is, it might have something to do with filter for FirstName and LastName, I have single Quote on Method #2 for those filter but not for Method #1.
我注意到的一件事是,它可能与FirstName和LastName的过滤器有关,对于那些过滤器,我在方法#2上有单引号,但对于方法#1没有。
What is wrong with Method # 1 ? 方法#1有什么问题?
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);
I've seen this countless times before. 我以前无数次见过这个。
I'm willing to bet that your columns are varChar
, but Dapper is sending in your parameters as nVarChar
. 我愿意打赌你的列是
varChar
,但是Dapper将你的参数发送为nVarChar
。 When that happens, SQL Server has to run a conversion on the value stored in each and every row. 发生这种情况时,SQL Server必须对存储在每一行中的值运行转换。 Besides being really slow, this prevents you from using indexes.
除了非常慢,这会阻止您使用索引。
See "Ansi Strings and varchar" in https://github.com/StackExchange/dapper-dot-net 请参阅https://github.com/StackExchange/dapper-dot-net中的 “Ansi字符串和varchar”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.