none
视图嵌套的性能问题 RRS feed

  • 问题

  • 以下是伪代码,大家应该能看懂

    select *from a join B join c join v1 

    v1

    select  * from  d join v2

    union

    select * from e join v2

    v2

    select * from f join v3 

    union all

    select * from g join v3

    v3

    select * from h

    union 

    select * from I

    类似的代码,这个查询执行时间大概10s 。问题,1,多层视图嵌套对性能会有影响吗?拆分掉视图,改用临时表对性能能否有提升

    或者是否有更好的实现方式

    2017年12月22日 7:52

答案

  • 非常感谢您的回复。您建议是实体表进行连接,就是用临时表作为缓冲,然后再和其他表连接的方式吗? 因为不可能直接把所有的表都join起来。 另外,语句的写法如果优化能否给个思路

    主要在于 union 和union all 的差异,可以把每个common table expression 当成虚表,具体请看示例代码,这样写应该符合语句的执行规则:

    ;with v3 as
    (
    select * from h
    union 
    select * from I
    ),
    v_1 as
    (
    select * from d
    union
    select * from e
    ),
    v_2 as 
    (
    select * from f
    union all
    select * from g
    )
    select * from v3 join v2 join v1

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月22日 13:20

全部回复

  • 用视图(普通视图,索引视图不一样,链接服务器视图也不一样) 和用直接在查询中用表

    效果是一样的,不管视图有没有嵌套,执行计划分析都会展开视图到表(除非你设置不不展开的选项)

    至于用临时表,这个很难评估,对于复杂的执行计划,使用临时表在某些时候会有效果,因为复杂执行计划容易选择到不佳的执行计划,而临时表可以帮助降低执行计划的复杂度,可以避免一些不佳的执行计划

    2017年12月22日 9:11
  • Hi owen_zeng,

    您好!多层视图嵌套对语句的查询性能当然会有影响,数据量少可能看不出明显的差别,但是,一旦查询的数据量比较大时,问题就明显暴露出来了,其实视图类似于虚拟表(例如子查询,表值函数,变量,common table expression),区别不是太大。

    根据SQL语句查询的执行顺序,建议最好基于实体表进行表连接,不要多层嵌套。(主要问题在于语句的写法需要优化)

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月22日 9:14
  • 非常感谢您的回复。您建议是实体表进行连接,就是用临时表作为缓冲,然后再和其他表连接的方式吗? 因为不可能直接把所有的表都join起来。 另外,语句的写法如果优化能否给个思路

    2017年12月22日 10:44
  • 感谢您的回复,嗯,就是说的普通视图。理论上影响应该不大,但是我认为还是有些影响的。不过这个理论上又说不上来。我经常使用的语句改写的方式就是临时表去拆分过于复杂的join。比如10几个表join的情况,通常来说还是有效果的。

    2017年12月22日 10:46
  • 非常感谢您的回复。您建议是实体表进行连接,就是用临时表作为缓冲,然后再和其他表连接的方式吗? 因为不可能直接把所有的表都join起来。 另外,语句的写法如果优化能否给个思路

    主要在于 union 和union all 的差异,可以把每个common table expression 当成虚表,具体请看示例代码,这样写应该符合语句的执行规则:

    ;with v3 as
    (
    select * from h
    union 
    select * from I
    ),
    v_1 as
    (
    select * from d
    union
    select * from e
    ),
    v_2 as 
    (
    select * from f
    union all
    select * from g
    )
    select * from v3 join v2 join v1

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年12月22日 13:20
  • 感谢您的回复,嗯,就是说的普通视图。理论上影响应该不大,但是我认为还是有些影响的。不过这个理论上又说不上来。我经常使用的语句改写的方式就是临时表去拆分过于复杂的join。比如10几个表join的情况,通常来说还是有效果的。

    你可以直接比较执行计划

    不要加把入了临时表的执行计划和 直接表、视图  这 两种方式做比较,我一直说的是后两种基本相同

    加临时表已经直接雷地豫执行计划了,这点前面已经说过

    2017年12月25日 1:27
  • 感谢,后续会用这种方式尝试一下。
    2017年12月25日 2:31
  • 这个我明白。我的意思就是后面两种方式,直接表,视图,是不是在某些情况下也有差异,比如视图嵌套过多的时候
    2017年12月25日 2:41
  • 这个我明白。我的意思就是后面两种方式,直接表,视图,是不是在某些情况下也有差异,比如视图嵌套过多的时候

    这个没有仔细比较过,毕竟嵌套太多,太复杂,执行计划也是头疼

    原理上来说,执行计划都是会展开视图的,所以用视图和直接用表应该差不多(写法完全一样的情况下,比如用 CTE 代替视图)

    索引视图、链接服务器视图、会随视图保存了 set 选项,些影响要排除

    2017年12月25日 3:06
  • 今天就遇到一个情况,,就是如果直接用表进行jion 大概7个表,然后where条件 能用到索引,速度很快1s。但是把join的表写成视图,然后对视图where 条件,就用不到索引。

    2018年1月4日 10:26
  • 能重现么?
    2018年1月5日 1:07