2014-07-08 62 views
2

我有具有以下定义SQL视图性能优化

create view mydashboard as 
SELECT distinct 
     cu.CrimeID, 
     ad.DeptID, 
     ad.CrimeDate, 
     cd.DeptIncidentID, 
     ad.crime, 
     u.username 
from alldatescrimes ad 
inner join crimeslist cl 
on 
ad.crime = cl.crime 
inner join users u 
on 
u.DeptID = ad.DeptID 
left join crimelookup cu 
on cu.CrimesListID = cl.CrimeListID 
left join crimesdetail cd 
on 
ad.CrimeDate = cast(cd.CrimeDate as date) 
and 
ad.DeptID = cd.DeptID 
and 
cu.CrimeID = cd.CrimeID 

我的问题是,如果我把where子句视图外,查询运行速度非常慢的视图。见下面的例子

select * 
from mydashboard 
where 

(username = 'john' 
or 
DeptIncidentID is null 
) 
and 
CrimeDate = '2014-06-16' 

相反如果我把同在视图内子句,查询在2-3秒内

非常fast..like运行

我的问题是我可以采取什么步骤所以如果我把where子句放在视图外面,查询运行得很快。我使用的这个观点在报告和查询运行很慢

问候 阿里夫

+1

你有没有建立索引? –

回答

1

MySQL有两个选项来处理查询中使用的视图:MERGE or TEMPTABLE

对于MERGE,引用视图和视图定义的语句的文本被合并,使得部分视图定义替换语句的相应部分。

对于TEMPTABLE,来自视图的结果被检索到一个临时表,然后用它来执行该语句。

由于视图定义中的DISTINCT子句,MySQL无法使用MERGE算法。它必须倒退到算法效率较低的TEMPTABLE

临时表没有索引,因此必须扫描整个表以处理外部WHERE条件。

您可能希望从视图定义中删除DISTINCT子句,并将其放入外部查询中。

+0

实际上,“DISTINCT”子句可能是多余的,因为您似乎从涉及的每个表中选择了“唯一”列。 – RandomSeed

0

这是有点长了评论。

MySQL在优化视图方面做得不好。事实上,documentation开始的一部分:

查看处理并没有得到优化

一个可能的问题是,MySQL已经确定需要的视图临时表。如果是这样,所有的处理都需要完成。然后在最后阶段,where条款正在被添加。 Here是关于“合并”与“临时表”的更多信息。