价值内联

有时,参数的便利性(在维护和表现力方面)可能会被其性能成本所抵消,以将其作为参数对待。例如,当页面大小由配置设置修复时。或者状态值与 enum 值匹配。考虑:

var orders = connection.Query<Order>(@"
select top (@count) * -- these brackets are an oddity of SQL Server
from Orders
where CustomerId = @customerId
and Status = @open", new { customerId, count = PageSize, open = OrderStatus.Open });

这里唯一真实的参数是 customerId - 另外两个是伪参数,实际上不会改变。如果将 RDBMS 检测为常量,RDBMS 通常可以做得更好。Dapper 有一个特殊的语法 - {=name} 而不是 @name - 它只适用于数字类型。 (这可以最大限度地减少 SQL 注入的任何攻击面)。一个例子如下:

var orders = connection.Query<Order>(@"
select top {=count} *
from Orders
where CustomerId = @customerId
and Status = {=open}", new { customerId, count = PageSize, open = OrderStatus.Open });

在发出 SQL 之前,Dapper 用文字替换值,因此 RDBMS 实际上看到如下内容:

select top 10 *
from Orders
where CustomerId = @customerId
and Status = 3

当允许 RDBMS 系统不仅做出更好的决策,而且打开实际参数阻止的查询计划时,这尤其有用。例如,如果列谓词针对参数,则不能使用在该列上具有特定值的筛选索引。这是因为下一个查询可能具有与这些指定值之一不同的参数。

使用文字值,查询优化器能够使用筛选的索引,因为它知道在将来的查询中值不会更改。