SQL 服务器 + Dapper 参数不起作用
SQL Server + Dapper parameter not working
使用Dapper + SQL服务器时,参数设置无效
FooNo、yyyyMMdd、Point分别是Char(8), Char(8), Char(4).
不工作
var parameters1 = new
{
FooNo = "00007829",
yyyyMMdd = "20210812",
Point = "001A"
};
var result = this.OpenedConn.Query(sql1, parameters1).ToList();
工作
sql1 = sql1.Replace("@FooNo", $@"'00007829'");
sql1 = sql1.Replace("@yyyyMMdd", $@"'20210812'");
sql1 = sql1.Replace("@Point", $@"'001A'");
var result = this.OpenedConn.Query(sql1).ToList();
SQL
SELECT COUNT([番号]) AS 登録数
FROM [dbo].[Foo]
WHERE ([施工先番号] = @FooNo) AND ([回収日] = @yyyyMMdd) AND ([ポイント] = @Point)
使用 dapper 分配参数的正确方法是什么?
您已经在正确使用参数,在第一个版本中不起作用。您提到错误是超时。这一点,结合内联文字版本有效的事实,让我得出结论,这里的问题是参数嗅探和查询计划重用。
上下文:当为查询生成查询计划时,它会为当时使用的参数赋予很大的权重 - 就理解数据分布而言。这通常是正确的,但如果数据严重偏斜,就会出现问题。在 Stack Overflow 内部,我们实际上(亲切地)称其为“Jon Skeet”问题——我的意思是:像 Jon Skeet 这样的用户(为了避免虚伪,我自己)非常对大多数用户而言,我们个人资料中的数据量不同。这可能会导致问题:
- 如果为大量用户生成查询计划,则生成的查询可能不适用于大多数“普通”用户
- 如果为“普通”用户生成查询计划,则生成的查询可能不适用于大量用户
这表现为比预期慢的查询(通常慢得多),观察到它们在直接执行时工作正常:因为我们强制执行不同的查询计划!
好消息是,解决方案通常很简单:“针对未知进行优化”
我的意思是:在现有查询之后添加 OPTION(OPTIMIZE FOR UNKNOWN)
。这有助于减少非典型数据在使查询计划偏向非典型数据方面可能产生的偏差。
SELECT COUNT([番号]) AS 登録数
FROM [dbo].[Foo]
WHERE ([施工先番号] = @FooNo) AND ([回収日] = @yyyyMMdd) AND ([ポイント] = @Point)
OPTION (OPTIMIZE FOR UNKNOWN)
使用Dapper + SQL服务器时,参数设置无效
FooNo、yyyyMMdd、Point分别是Char(8), Char(8), Char(4).
不工作
var parameters1 = new
{
FooNo = "00007829",
yyyyMMdd = "20210812",
Point = "001A"
};
var result = this.OpenedConn.Query(sql1, parameters1).ToList();
工作
sql1 = sql1.Replace("@FooNo", $@"'00007829'");
sql1 = sql1.Replace("@yyyyMMdd", $@"'20210812'");
sql1 = sql1.Replace("@Point", $@"'001A'");
var result = this.OpenedConn.Query(sql1).ToList();
SQL
SELECT COUNT([番号]) AS 登録数
FROM [dbo].[Foo]
WHERE ([施工先番号] = @FooNo) AND ([回収日] = @yyyyMMdd) AND ([ポイント] = @Point)
使用 dapper 分配参数的正确方法是什么?
您已经在正确使用参数,在第一个版本中不起作用。您提到错误是超时。这一点,结合内联文字版本有效的事实,让我得出结论,这里的问题是参数嗅探和查询计划重用。
上下文:当为查询生成查询计划时,它会为当时使用的参数赋予很大的权重 - 就理解数据分布而言。这通常是正确的,但如果数据严重偏斜,就会出现问题。在 Stack Overflow 内部,我们实际上(亲切地)称其为“Jon Skeet”问题——我的意思是:像 Jon Skeet 这样的用户(为了避免虚伪,我自己)非常对大多数用户而言,我们个人资料中的数据量不同。这可能会导致问题:
- 如果为大量用户生成查询计划,则生成的查询可能不适用于大多数“普通”用户
- 如果为“普通”用户生成查询计划,则生成的查询可能不适用于大量用户
这表现为比预期慢的查询(通常慢得多),观察到它们在直接执行时工作正常:因为我们强制执行不同的查询计划!
好消息是,解决方案通常很简单:“针对未知进行优化”
我的意思是:在现有查询之后添加 OPTION(OPTIMIZE FOR UNKNOWN)
。这有助于减少非典型数据在使查询计划偏向非典型数据方面可能产生的偏差。
SELECT COUNT([番号]) AS 登録数
FROM [dbo].[Foo]
WHERE ([施工先番号] = @FooNo) AND ([回収日] = @yyyyMMdd) AND ([ポイント] = @Point)
OPTION (OPTIMIZE FOR UNKNOWN)