Ash*_*rya 6 sql performance union view sql-server-2008
我有一个简单的查询调整问题,它是
我们可以改善具有以下定义的视图的性能吗?
SELECT * FROM A
UNION ALL
SELECT * FROM B
而且效果太差,以至于6.5k记录需要12秒
任何帮助表示赞赏。
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
有没有理由让你把这两个不放在同一张桌子上,无论你做什么,最终都会很糟糕。如果可能,请考虑迁移到一张表。如果没有,您始终可以通过将它们全部插入到同一事物中来“具体化视图”。
话虽这么说,您不会在联合上选择 *,如果视图顶部有特定条件,则可以通过对该列建立索引来提高性能。
如果您告诉每个人这适用于哪个特定数据库,将会有所帮助。
| 归档时间: |
|
| 查看次数: |
16259 次 |
| 最近记录: |