收录日期:2020/10/20 20:28:29 时间:2016/07/19 20:29:27 标签:疑难问题
今天发现了一个 有趣的问题~



DECLARE
@BrandCode varchar(4) = 'E',
@StartDate char(8) = '20100101',
@EndDate           char(8) = '20100113'

SELECT A.Code,A.ShopCode,B.ProdCode,
SUM(...),
SUM(...),
...
 FROM Mst AS A
INNER JOIN Dtl  AS B ON A.No = B.No AND A.Code = B.Code
 WHERE A.Code = @Code
   AND A.Date >= @StartDate
   AND A.Date <= @EndDate      
   AND A.DelChk = 0
   AND B.DelChk = 0
 GROUP BY A.Code,A.ShopCode,B.ProdCode

--------直接给参数

SELECT A.Code,A.ShopCode,B.ProdCode,
SUM(...),
SUM(...),
...
 FROM Mst AS A
INNER JOIN Dtl  AS B ON A.No = B.No AND A.Code = B.Code
 WHERE A.Code = 'E'
   AND A.Date >= '20100101'
   AND A.Date <= '20100113'      
   AND A.DelChk = 0
   AND B.DelChk = 0
 GROUP BY A.Code,A.ShopCode,B.ProdCode


这两个语句性能上居然有很大差距

给定义参数和 没定义参数的时候给的执行计划不一样
上面的慢的很多~

为什么给参数和直接赋值会有不同的执行计划啊?

有没有好办法解决这个问题呢?
这是个老问题
引用 1 楼 yang_ 的回复:
这是个老问题


海爷解释下?
引用 2 楼 fredrickhu 的回复:
引用 1 楼 yang_ 的回复:
 这是个老问题


 海爷解释下?
美女给解释下
引用 1 楼 yang_ 的回复:
这是个老问题

呵呵,应该用强制参数化来执行是吧
这确实是个老问题 
有没有什么方案啊? 
好像相差是否很大 的一个关键因素是 符合条件的记录数目的多少
结果是看日期的 日期间隔长了 结果数据就很多  日期间隔少就 那么一些结果
我是先这么解决问题了~

不知道大家还有没有别的办法~


DEClARE @SQL NVARCHAR(MAX)

DECLARE
    @Code    varchar(4) = 'E',
    @StartDate    char(8) = '20100101',
    @EndDate              char(8) = '20100113'
SET @SQL = N'
SELECT A.Code,A.ShopCode,B.ProdCode,
SUM(...),
SUM(...),
...
 FROM Mst AS A
    INNER JOIN Dtl  AS B ON A.No = B.No AND A.Code = B.Code
 WHERE A.Code = ''' + @Code + '''
   AND A.Date >= ''' + @StartDate + '''
   AND A.Date <= ''' + @EndDate + '''        
   AND A.DelChk = 0
   AND B.DelChk = 0
 GROUP BY A.Code,A.ShopCode,B.ProdCode'
 
EXEC(@SQL)

--这么生成一个PROC 之后调用的时候 先把这些数据添加到临时表 在给这个临时表建立索引,之后JOIN
这个本来是 FUNCTION 的
只能该做 存储过程了~ 
因为用的地方很多~ 
也是在太长了~

大家有没有别的好方法吗?
LZ 可以直接看 
Inside Microsoft SQL Server 2005: T-SQL Programming
-> Chapter 7: Stored Procedures
-> Compilations, Recompilations, and Reuse of Execution Plans
-> Parameter Sniffing Problem
引用 11 楼 xman_78tom 的回复:
LZ 可以直接看
Inside Microsoft SQL Server 2005: T-SQL Programming
-> Chapter 7: Stored Procedures
-> Compilations, Recompilations, and Reuse of Execution Plans
-> Parameter Sniffing Problem

我就说哪里见过。。

果然
使用参数将常量与 SQL 语句分隔开有助于关系引擎识别重复计划。可以按下列方式使用参数: 

在 Transact-SQL 中,使用 sp_executesql: 

 复制代码 
DECLARE @MyIntParm INT
SET @MyIntParm = 1
EXEC sp_executesql
  N'SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = @Parm',
  N'@Parm INT',
  @MyIntParm
 
建议对动态生成 SQL 语句的触发器、Transact-SQL 脚本或存储过程使用此方法。 


ADO、OLE DB 和 ODBC 使用参数标记。参数标记是问号 (?),在 SQL 语句中替代常量并绑定到程序变量。例如,可以在 ODBC 应用程序中执行下列操作: 


使用 SQLBindParameter 将整数变量绑定到 SQL 语句中的第一个参数标记。


为变量赋整数值。


执行语句,并指定参数标记 (?): 

 复制代码 
SQLExecDirect(hstmt, 
  "SELECT * FROM AdventureWorks.Production.Product WHERE ProductSubcategoryID = ?",
  SQL_NTS);
 
在应用程序中使用参数标记时,SQL Server 附带的 SQL Server Native Client OLE DB 访问接口和 SQL Server Native Client ODBC 驱动程序使用 sp_executesql 将语句发送到 SQL Server。


设计使用参数的存储过程。


如果不将参数显式地置入应用程序的设计中,则也可以依赖 SQL Server 查询优化器使用 简单参数化 的默认行为自动参数化某些查询。另外,也可以通过将 ALTER DATABASE 语句的 PARAMETERIZATION 选项设置为 FORCED,强制查询优化器考虑将数据库中的所有查询参数化。有关详细信息,请参阅强制参数化。
强制参数化,或参数标志

在英文XP下如何让VC6可以使用中文字符集? 和C#语言比较,用Delphi for .NET语言开发.NET程序好吗?(请只探讨语言层面) norton ghost9.0的问题,望大虾解决,谢(在线等) 请教一个删除语句? 2004年-2005年软件行业的主流技术讨论! 抵制日货能让中国强大吗? DELPHI 6.0的INDY Mail Demo邮件例子程序是不是有问题. QQ上显示的IP地址没有了 关于php的一个不懂的问题! PHP书籍怎么就这么少? 那位大哥知道WINXP开机和关机的音乐在那里设,位置在那里? 其实....... 菜鸟的问题呀请大家帮帮我先给大家拜个年哦 春节联欢晚会中的日货 如何应用Code Access Security把代码保护起来,不致被第三方不正确调用? 请教J2MEUnit的问题 大家能不能推荐几个好的关于ASP.NET技术的好网站啊,中文可以,英文也可以 关于VB的配色困惑 XP系统的用户问题(在线等) 如何在水晶报表里显示图象? 你(男士)同居了吗?你家里知道你们同居吗?如果知道并强烈反对同居怎么办?...欢迎男女士支招! 请教如何更改显示器刷新率 编译出现unchecked for details是为什么?那里出错? 用struct和typedef struct 定义一个结构体有什么区别?为什么会有两种方式呢? 以下C#代码如何改为vb.net代码?? 大家有没有空,搞个中国地图,的系统呀。 企业上网问题 jbuilder不能调试的问题,急需解决! 新年向大家问好!问个Session的小问题(100分) DBgrid中要判断用户输入的资料是否合法,不合法时焦点不允许离开.应该在哪里写代码?