动态SQL笔记

举报
ys6687323 发表于 2021/06/30 14:58:21 2021/06/30
【摘要】 动态SQL,就是将查询条件中的判断语句,提前在代码中判断完成,而放到数据库(如SQL Server)中执行时就是简单的、可利用索引的SQL语句了,在这个例子中,判断@userId和@menuId是否为null的代码,可能会长这个样子(如果是Dapper):var sql = new StringBuilder();sql.Append("SELECT * FROM FoodOrder WHE...

动态SQL,就是将查询条件中的判断语句,提前在代码中判断完成,而放到数据库(如SQL Server)中执行时就是简单的、可利用索引的SQL语句了,在这个例子中,判断@userId@menuId是否为null的代码,可能会长这个样子(如果是Dapper):

var sql = new StringBuilder();
sql.Append("SELECT * FROM FoodOrder WHERE 1=1 ");

if (userId != null) 
{
    sql.AppendLine("AND OrderUserId = @userId");
}

if (menuId != null)
{
    sql.AppendLine("AND FoodMenuId = @menuId");
}
// ...

如果是EF,代码可能是这个样子:

IQueryable<FoodOrder> query = db.FoodOrders;

if (userId != null)
{
    query = query.Where(x => x.OrderUserId == userId);
}

if (menuId != null)
{
    query = query.Where(x => x.FoodMenuId = menuId);
}
// ...

这样一来,最终在数据中执行的SQL语句就比较简单了,如果客户确实传了userIdmenuId两个参数,SQL就应该长这个样子:

select * from FoodOrder where 
	OrderUserId = @userId AND 
	FoodMenuId = @menuId

运行的set statistics io on结果如下:

(3 行受影响)
Table 'FoodOrder'. Scan count 2, logical reads 11, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

显然仅进行了11次逻辑读(相比静态SQL337次),然后执行计划如下:

显示进行了两次Index Seek,显然是走了索引,显示查询开销只占5%,而之前的开销占95%,性能区别高达20倍以上。

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。