结果集每一行的UNION ALL

时间:2019-09-06 14:42:19

标签: sql sql-server union

如果输入一个参数,即:

,我的视图可以快速运行
SELECT * FROM v_myView WHERE myVal = 'thisValue';

如果我要求它提供多个值IN,它将花费大约20秒的时间来评估整个视图的数据,并从数据中选择结果。所以这很慢:

SELECT * FROM v_myView WHERE myVal IN (SELECT theseValues FROM myTable);

我要记住,对于我知道的数据集很小的情况,从SELECT theseValues FROM myTablev_myView分别查询UNION ALL的所有结果将更快一些这样我就可以有效地生成查询:

SELECT * FROM v_myView WHERE myVal = 'thisValue1'
UNION ALL
SELECT * FROM v_myView WHERE myVal = 'thisValue2'
UNION ALL
etc...;

是否有任何方法可以在不使用存储过程或动态sql的情况下在“简单”查询中强制执行此操作,还是我将不得不长期这样做?

1 个答案:

答案 0 :(得分:0)

看看执行计划以及基础表和视图的结构,可以更好地回答问题。

通常,使用EXISTS可以在三种常用的方法中获得最佳性能:

  1. 存在
  2. 内部加入
  3. IN

但是,比较取决于基础表的结构和索引。

  • 以某种方式使搜索在找到匹配项时就会使搜索短路,这比其他两种方法都更好。

查询:

SELECT  *
FROM    v_myView V 
WHERE   EXISTS   (
                    SELECT 1
                    FROM   myTable T
                    WHERE  T.theseValues = V.myVal
                 );

但是查询也应该包含必需的索引,以便能够获得良好的性能:

    v_myView视图的基础表的
  1. myVal列应具有非聚集行存储索引(除非myVal已经是该表的聚集索引键)。
  2. myTable的这些values列应具有非聚集行存储索引(除非theseValues已经是表的聚集索引键)
  3. 您是否需要在最终结果中获取视图v_myView的所有列?我建议您仅获取结果中所需的列。所选列应通过使用带有INCLUDE子句的非聚集行存储索引来覆盖,或创建一个覆盖每个基础表的那些列的单个非聚集列存储索引。