2014-07-08 92 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是關於「合併」與「臨時表」的更多信息。