如何用Union All优化视图

时间:2016-04-20 17:32:18

标签: sql sql-server query-optimization

我有一个带有union all的两个单独查询的视图。例如:

CREATE VIEW MyView AS

SELECT foo.id, bar.data
FROM foo
INNER JOIN bar ON foo.id = bar.id

UNION ALL

SELECT baz.id, baz.data
FROM baz

然后我对这个视图运行一个select语句:

SELECT * FROM MyView WHERE id = 1

id为1仅存在于第一个select语句中。具有foobar表的那个,但与baz表的联合仍然导致它运行得更慢。如果拿出工会,它会更快。我必须把它留在那里,因为有时会使用一个id来返回第二个select语句的结果。

我的问题是:有没有办法帮助sql server知道union的第二部分都没有结果,所以它不必运行该查询?

所有这些数据都在一张表中。这是一个新的数据结构,我们所有的旧应用程序都将依赖此视图从这个新的数据结构中读取数据。这就是为什么我们事先不知道哪个表实际上会有结果。

2 个答案:

答案 0 :(得分:0)

有一种方法可以进行条件联合连接。通过查找执行计划,尝试查看它是否有助于加快查询速度。也许你的瓶颈不是你想的那么?

SELECT foo.id, bar.data
FROM foo
INNER JOIN bar ON foo.id = bar.id

UNION ALL

SELECT baz.id, baz.data
FROM baz
WHERE baz.id = @idSearched

如果您不打算进行任何编辑,带参数的Sproc可能会替代视图。

CREATE PROCEDURE procName 
-- Add the parameters for the stored procedure here
@id INT = 1
AS
BEGIN
 SET NOCOUNT ON;

 SELECT foo.id, bar.data
 FROM foo
 INNER JOIN bar ON foo.id = bar.id

 UNION ALL

 SELECT baz.id, baz.data
 FROM baz
 WHERE baz.id = @id
END
GO

如果您绝对需要像table这样的视图,请使用以下格式实现存储函数:

CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
   SELECT * FROM emp WHERE emp_id=@pintEno;
This allows you to use it as a normal view, with:
--Query it like :
SELECT * FROM v_emp(10)

答案 1 :(得分:-1)

你有baz(id)的索引吗?我希望这个查询可以使用一个索引:

SELECT foo.id, bar.data
FROM foo
INNER JOIN bar ON foo.id = bar.id
UNION ALL
SELECT baz.id, baz.data
FROM baz
WHERE baz.id;