一个奇怪的问题

dbaren 2013-04-05 01:25:05
今天在做一个统计功能时,写了一个存储过程,该存储过程就是接受两个日期型参数,返回一个统计后的数据集,在存储过程中使用了两个表的联合查询,写完后,用exec运行了下,速度很慢,经过调查后,我把其中一个表中的GUID列加了一个聚集索引,然后针对这个表重建了下索引,然后再用exec跑了下该存储过程,结果快多了,一秒钟即可,以前的话需要17秒,后来我发现逻辑不对,就又在where子句后加了一个条件,然后再用exec跑了下该存储过程,结果又需要17秒钟了,然后我就又针对该表重建了下索引(使用DBCC),然后再用exec跑了下该存储过程,结果1秒钟就出来了,然后我又改了下where子句,结果跑一次又需要17秒钟了,然后重建索引又好了

现在就是感觉只要动一下那个存储过程的where子句,哪怕是在后面加一个 " and 1=1",然后跑起来就N慢,需要17秒,必须得重建索引才行,索引重建后跑一次只需要1秒

请问哪位有数据库优化经验的高手能给个说法这是为什么吗,给个参考也行 谢谢
...全文
280 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dbaren 2013-04-05
  • 打赏
  • 举报
回复
将动态sql改为静态sql,还是采用传递参数调用存储过程,该问题成功解决
SQL77 2013-04-05
  • 打赏
  • 举报
回复
引用 9 楼 dbaren 的回复:
嗯 我建了个唯一非聚集索引,效果不错,不过每次修改后还是要重建索引,不过这个问题我大概也明白了,可能和动态sql执行计划的选择有关系,执行计划没有重用,待我有时间好好研究下,谢谢SQL77这位高手的提醒和建议
存储过程的定义你怎么老是要改呢?你不重建索引,你多次执行同一参数,你可以用跟踪器跟踪一下看是否是编译的时间长.要用同一组参数.
dbaren 2013-04-05
  • 打赏
  • 举报
回复
嗯 我建了个唯一非聚集索引,效果不错,不过每次修改后还是要重建索引,不过这个问题我大概也明白了,可能和动态sql执行计划的选择有关系,执行计划没有重用,待我有时间好好研究下,谢谢SQL77这位高手的提醒和建议
dbaren 2013-04-05
  • 打赏
  • 举报
回复
引用 6 楼 SQL77 的回复:
引用 5 楼 dbaren 的回复:1.去掉这个聚集索引后,查询永远很慢,我们是二期项目,里面有用户的真实数据,数据库的设计就只能这个样了,所以guid字段也不能改成int类型的 2.where的条件是传参数进去的 1GUID列可以改用唯一非聚集索引.(因为你要传入GUID.(最好加另一列为聚集),能满足你的性能) 2我问的意思是 AND 1=1 是你直接传进去的?……
and 1=1 是我在动态sql里写死的
dbaren 2013-04-05
  • 打赏
  • 举报
回复
引用 5 楼 dbaren 的回复:
1.去掉这个聚集索引后,查询永远很慢,我们是二期项目,里面有用户的真实数据,数据库的设计就只能这个样了,所以guid字段也不能改成int类型的 2.where的条件是传参数进去的
关于第2点 我再说一下,准确的说,我是通过传参数调用存储过程,存储过程中把接受到的参数值拼接到一个sql字符串中,然后使用exec(@strSql)这样去运行这个动态的sql语句从而返回这个动态sql语句的查询结果
SQL77 2013-04-05
  • 打赏
  • 举报
回复
引用 5 楼 dbaren 的回复:
1.去掉这个聚集索引后,查询永远很慢,我们是二期项目,里面有用户的真实数据,数据库的设计就只能这个样了,所以guid字段也不能改成int类型的 2.where的条件是传参数进去的
1GUID列可以改用唯一非聚集索引.(因为你要传入GUID.(最好加另一列为聚集),能满足你的性能) 2我问的意思是 AND 1=1 是你直接传进去的?
dbaren 2013-04-05
  • 打赏
  • 举报
回复
1.去掉这个聚集索引后,查询永远很慢,我们是二期项目,里面有用户的真实数据,数据库的设计就只能这个样了,所以guid字段也不能改成int类型的 2.where的条件是传参数进去的
SQL77 2013-04-05
  • 打赏
  • 举报
回复
引用 3 楼 dbaren 的回复:
我并不是非要加一个" and 1=1",我的意思是指,在开发过程调试中难免会改动这个where语句,难道每次改动where语句后哪怕很简单的改动,都要重建这个表的索引才能达到和改动前相当的效率吗 例如: 改动前:select xxx from mmmm where WorkInsGUID='F9E01CD7-6E62-42B7-9423-6D9067D75736',重建索引后 查询效率:1……
1.GUID加聚集索引是不明智的选择.索引碎片太容易产生了.--把聚集索引去掉吧. 2.你动态拼接WHERE 是传参数进去的还是里面去写好的?如果你没弄好.可能重新编译.或者重新使用执行计划不准确.
dbaren 2013-04-05
  • 打赏
  • 举报
回复
我并不是非要加一个" and 1=1",我的意思是指,在开发过程调试中难免会改动这个where语句,难道每次改动where语句后哪怕很简单的改动,都要重建这个表的索引才能达到和改动前相当的效率吗 例如: 改动前:select xxx from mmmm where WorkInsGUID='F9E01CD7-6E62-42B7-9423-6D9067D75736',重建索引后 查询效率:1秒 然后改成:select xxx from mmmm where WorkInsGUID='F9E01CD7-6E62-42B7-9423-6D9067D75736' and 1=1 查询效率:17秒,必须重建mmmm表的索引后,查询效率又恢复到1秒 这是为什么呢,我仅仅只是加了一个"1=1"的查询条件啊,根本就没动mmmm表的索引啊
---涛声依旧--- 2013-04-05
  • 打赏
  • 举报
回复
在后面为什么要加一个 " and 1=1"? where 后面尽量将主键、聚簇索引、非聚簇索引放在左边,一旦将 1=1 放在了最左边,索引将不会起作用的
SQL77 2013-04-05
  • 打赏
  • 举报
回复
每次改WHERE 不一样么? 你改了语句当然要重新编译啦.(很大可能)

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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