当采用下列查询语句时
declare @uid = 10 
select * 
from A 扫描了3个子表,使得查询的速度慢了3倍,sql2000的分区视图真是令人费解啊!!!!

解决方案 »

  1.   

    因为 where uid=@uid
    使用的变量,分析成本时,并不计算变量值,无法估计uid可能出现在哪个表,所以先在各个表中预描。而 where uid=10 时,因为分区视图创建时确定了边界值,因此会确定扫描范围。
      

  2.   

    你是问在简单语句中,还是存储过程中?存储过程中,被编译的和被缓存的计划只是指可以被确定的东西。可能一些概念说不太清。
    create proc
    as
     ... exec(@s)
    go它编译的就是里面的语句体,而@s执行的是什么,只有运行中编译,@s里的语句是没有编译和计划缓存的。对于你的分区视图一样的,即使在存储过程中,也是一样的道理,存储过程执行时,它只知道是 select * from v where uid=@uid
    至于怎么扫描,仍未确定。我的意思并不是说,当这样的查询语句加入存储过程后,就能确定它扫哪个表了。
      

  3.   

    楼上朋友意思是,即使是在存储过程,执行下面语句,
    declare @uid = 10 
    select * 
    from A 
    where uid = @uid 
    也会扫描所有子表.再问,那么我使用动态语句,这样来执行呢?
    declare @uid = 10 
    declare @sqlStr varchar(8000)
    set @sqlStr = '
    select * 
    from A 
    where uid = ' + str(@uid )
    exec(@sqlStr)
    这样,是不是让编译器执行前就认定了uid的确定值,而只会去扫描一个表了?
      

  4.   

    哈哈,我在查询分析器中用exec(@sqlStr) 的方式执行,果然就只扫描了一个表.只有当uid不存在时,才会扫描所有表.
    那么是不是在存储过程中,多使用exec(@sqlStr) 的方式来执行查询语句,反而效率更高呢?
    当然生成查询字符串也要消耗一定资源,但我认为字符串的处理应该非常快,可以忽略不计.
      

  5.   

    是不是可以总结为:
    在存储过程中对"分区视图"进行查询时,一定要先生成字符串查询语句,使得查询
    条件中的变量变成确定值,然后用exec()的方式来执行.当然,这时无法将查询结果生成中间变量了.