高分求解!为什么拼接的SQL语句比参数化的查询快???

雪狐 2013-03-21 01:24:18
数据库是SQL2000,记录行数700万行左右。mssql驱动包:sqljdbc4.jar
用拼接的SQL语句:
SELECT * FROM UserInfo WHERE userID = 'aaa' AND DATEDIFF(DAY, deadline, GETDATE()) <= 0;
比参数化的语句:
SELECT * FROM UserInfo WHERE userID = ? AND DATEDIFF(DAY, deadline, GETDATE()) <= 0;
要快很多,为什么?求大神们给个解释,谢谢!
理论上讲,SQLServer为了避免SQL语句二次编译,参数化查询比拼接的SQL要快。。
但是这个为啥是这样的??
...全文
635 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
华芸智森 2014-08-14
  • 打赏
  • 举报
回复
你这个叫参数化执行?
Janway 2013-10-05
  • 打赏
  • 举报
回复
使用参数化查询时,如果只是指定了参数名、参数值,其执行效率低于纯SQL语句(或拼接);如果同时指定参数名、值、类型、长度(字符型)则执行效率高于纯SQL语句(或拼接)。网上找到的解释是:命中了查询计划。 我的试验条件是: SQL2008R2 600w记录 最后结论:如果记录很少,或者仅一次查询,参数化查询的效率优势不明显,甚至可以说很差。当然这不代表可以放弃使用参数化查询,比忘了它至少很安全。
雪狐 2013-03-21
  • 打赏
  • 举报
回复
引用 10 楼 preferme 的回复:
这种带参数的使用方式,要用PreparedStatement而不要用普通的Statement对象,两者性能差别很大。 另外,这些对象也是能够重用的,没必要一次查询就创建一个新的对象。
是用的PreparedStatement类,对象也是重用的,只是在才查询的时候将para 清理掉重新设置了一下。
冰思雨 2013-03-21
  • 打赏
  • 举报
回复
这种带参数的使用方式,要用PreparedStatement而不要用普通的Statement对象,两者性能差别很大。 另外,这些对象也是能够重用的,没必要一次查询就创建一个新的对象。
雪狐 2013-03-21
  • 打赏
  • 举报
回复
引用 8 楼 forgetsam 的回复:
引用 4 楼 foxflyhigher 的回复:忘了说了,不是一次select,运用上是上万次的select! 一秒执行上万次,还是一天上万次,还是一次上万条,你把这个搞清楚。一天上万次就不用当事。 或者干脆一点,用户操作一次,你的这条SQL走几次?一百次以内,不用考虑解析带来的效率问题。 按照你的描述,就一个可能:写'aaa',数据库根据统计信息,决定……
具体应用是这样的:我从A出获取到了用户ID,要从B处获取用户的部分信息,然后再从C出获取用户部分信息,是一秒要执行上万次。刚开始是用?的方式循环,发现很慢,然后改成直接'aaa'的方式,就很快,两种方式的时间差为2到3秒,什么原因,我很疑惑。鉴于权限原因,我无法监控到服务器SQL的执行状态。 但从查询分析器上的'aaa'模式,走的是主键索引,这是没有问题的。
forgetsam 2013-03-21
  • 打赏
  • 举报
回复
引用 4 楼 foxflyhigher 的回复:
忘了说了,不是一次select,运用上是上万次的select!
一秒执行上万次,还是一天上万次,还是一次上万条,你把这个搞清楚。一天上万次就不用当事。 或者干脆一点,用户操作一次,你的这条SQL走几次?一百次以内,不用考虑解析带来的效率问题。 按照你的描述,就一个可能:写'aaa',数据库根据统计信息,决定走索引;用?,数据库无法预知,采用全表扫描。
雪狐 2013-03-21
  • 打赏
  • 举报
回复
引用 2 楼 fangmingshijie 的回复:
这是肯定的,要花时间去找?的值。
那也不至于慢那么多吧,具体的时间差,我打印出来都2到3秒了。。。
谜斯特段 2013-03-21
  • 打赏
  • 举报
回复
楼上有人说的对,给参数赋值也需要时间啊,要先解析字串,找到问号,然后再拼成查询语句,当然慢了。
雪狐 2013-03-21
  • 打赏
  • 举报
回复
参数化查询慢,我是通过打印时间差来的,在初始化stmt的时候给开始时间,查询完毕给结束时间,然后算时间差!
引用 2 楼 fangmingshijie 的回复:
这是肯定的,要花时间去找?的值。
这个就是慢,也不至于慢好几秒吧。 同样的查询,拼SQL语句,几乎忽略不计,然参数化查询则需要2到3秒。。。
雪狐 2013-03-21
  • 打赏
  • 举报
回复
忘了说了,不是一次select,运用上是上万次的select!
zoeg 2013-03-21
  • 打赏
  • 举报
回复
真的像你说的预编译比直接编译执行慢?我看未必!至少我觉得你测试和论断的依据只是主观的感觉,这个无从稽考,姑且不理会它! 我只注意到你的第二个条件:DATEDIFF(DAY, deadline, GETDATE()) <= 0,你的第一个条件根据UserID来筛选,通常来说如果有索引已经非常高效了,但是我担心的是,你两次不同的执行方式下,执行计划可能不一样,如果条件筛选是DATEDIFF(DAY, deadline, GETDATE()) <= 0先进行,那会进行一次全表扫描,不慢才怪! 看你这个条件应该是选择某个时间阀之后的数据,我觉得你可以修改成 deadline>(想办法用常量计算出今天凌晨0点时刻,这个我不懂)。 通常来说,你需要非常注意你的sql条件中对字段进行加工后的筛选,这很有可能导致数据库对全表进行一次完全扫描,例外的是如果执行计划让UserID=?优先执行,那么在过滤后的小范围内扫描,这个问题就不那么明显了! 一般而言,数据库的执行计划是比较聪明的,但是也不要过于相信,有时候它也犯傻,所以重点还是分析两次执行时使用的执行计划,以上意见仅供参考,sqlserver用的少,不过概念应该可以通用的,你可以朝这个方向找找问题!
  • 打赏
  • 举报
回复
这是肯定的,要花时间去找?的值。
forgetsam 2013-03-21
  • 打赏
  • 举报
回复
理论上讲,SQLServer为了避免SQL语句二次编译,参数化查询比拼接的SQL要快。。
扯淡,那是insert时候,不用绑定变量几千万条语句编译几千万次,加了绑定变量变成一个编译结果用不同的参数调几千万次,所以才快。 你一共就一条select,编译一次也就几毫秒,你能觉出来慢? 把参数写死到SQL里,数据库会读到这个值,根据之前收集的数据统计信息,可能会优化查询方案(只是可能),用绑定变量则数据库只有生成查询方案后才能得到这个值,所以可能走了错误的查询方案

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧