简单联合的情况下的SQL查询性能

Ash*_*rya 6 sql performance union view sql-server-2008

我有一个简单的查询调整问题,它是

我们可以改善具有以下定义的视图的性能吗?

SELECT * FROM A UNION ALL SELECT * FROM B

而且效果太差,以至于6.5k记录需要12秒

任何帮助表示赞赏。

Boh*_*ian 5

union像这样的视图存在的问题是,优化器无法通过视图访问表的原始列,因此在使用这种视图时:

select * from myview where foo = 5
Run Code Online (Sandbox Code Playgroud)

where子句是视图传递的整个行集的过滤器,因此两个表中的所有行在联合之后都进行处理,因此将不使用索引。

为了对性能抱有希望,您必须以某种方式在视图内部获取所需条件并将其应用于每个表,但要使其保持可变状态,以便在使用时可以应用不同的条件。

我找到了解决此问题的方法。这有点hacky,不能同时使用,但可以!尝试这个:

 create table myview_criteria(val int);
 insert into myview_criteria values (0); -- it should have exactly one row

 create view myview as
 SELECT * FROM A
 WHERE foo = (select val from myview_criteria)
 UNION ALL
 SELECT * FROM B
 WHERE foo = (select val from myview_criteria);
Run Code Online (Sandbox Code Playgroud)

然后使用它:

update myview_criteria set val = 5;
select * from myview;
Run Code Online (Sandbox Code Playgroud)

假设在上有一个索引foo,则将使用该索引。

注意此处,因为很明显,当同时执行多个执行时,此技术将无法工作。


小智 1

有没有理由让你把这两个不放在同一张桌子上,无论你做什么,最终都会很糟糕。如果可能,请考虑迁移到一张表。如果没有,您始终可以通过将它们全部插入到同一事物中来“具体化视图”。


话虽这么说,您不会在联合上选择 *,如果视图顶部有特定条件,则可以通过对该列建立索引来提高性能。

如果您告诉每个人这适用于哪个特定数据库,将会有所帮助。