2011-07-07 59 views
3

我有一個VIEW這是SLOW。我不喜歡VIEW語句,因爲有很多JOINSUNION如何優化此VIEW語句?

以下是查看語句。

Create VIEW NewView AS 

SELECT t2.* FROM Table1 t1 
JOIN Table2 t2 
ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2 
WHERE t1.Column3 !='String' 

UNION 

SELECT t1.*, 'Add this string to the Last Column' FROM Table1 t1 
LEFT JOIN Table2 t2 
ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2 
WHERE t2.Column1 is null OR t1.Column3 ='String' 
ORDER BY Column 4 

基本想法是,如果記錄存在於Table1Table2,從Table2記錄應從Table1覆蓋的記錄。我怎樣才能優化這個?

我在這兩個表中都有一個主鍵id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,但我不知道如何將它與視圖集成在一起。我希望視圖具有主鍵或複合鍵。我無法使用其他列,因爲所有列都可以具有空值和重複值。

+2

你需要'ORDER BY'在'VIEW'? – onedaywhen

+0

我不知道我會將一個'UNION'和兩個'JOIN'分類爲「批次」 –

+0

我確實需要在視圖本身中使用ORDER BY。如果沒有,我必須在從視圖中獲取數據的每個查詢中進行ORDER BY(frond end)。這是我想要的默認顯示。 – theking963

回答

3

您可以使用外連接進行連接和比較,然後使用COALESCE來優先選擇T2到T1。

要保留一個唯一的密鑰,並假設您的ID都是正數,您可以使一個表的ID爲負數。

SELECT 
    COALESCE(t2.id,  -t1.id)  AS id, 
    COALESCE(t2.Column1, t1.Column1) AS Column1, 
    COALESCE(t2.Column2, t1.Column2) AS Column2 
FROM 
    Table1   AS t1 
FULL OUTER JOIN 
    Table2   AS t2 
    ON t1.Column1 = t2.Column2 
    AND t1.Column2 = t2.Column2 
WHERE 
    COALESCE(t2.Column3, t1.Column3) = 'String' 

編輯:

關於選擇哪些表有precidence,你可以使用CASE語句更復雜的規則......

(這並不與上面相同,但可修改爲不同precidence規則。)

SELECT 
    CASE WHEN t2.id IS NULL THEN -t1.id  ELSE t2.id  END AS id, 
    CASE WHEN t2.id IS NULL THEN t1.Column1 ELSE t2.Column1 END AS Column1, 
    CASE WHEN t2.id IS NULL THEN t1.Column2 ELSE t2.Column2 END AS Column2 
FROM 
    Table1   AS t1 
FULL OUTER JOIN 
    Table2   AS t2 
    ON t1.Column1 = t2.Column2 
    AND t1.Column2 = t2.Column2 
WHERE 
    COALESCE(t2.Column3, t1.Column3) = 'String' 
+0

根據他需要左連接的例子。 – Karolis

+0

我喜歡負面的id主意。你的查詢看起來很有趣,我將嘗試一下。 – theking963

+0

需要左連接而不是外連接,但您的想法有效:) – theking963

2

如果你確信不會有重複的,那麼你可以通過replaceng UNIONUNION ALL沒有ALL查詢的結果進行排序,並重復的將被刪除時UNIONing推動它。請參閱http://dev.mysql.com/doc/refman/5.0/en/union.html

+0

有重複的列值。這是在最後的問題中說明的。附:你是指重複的記錄集或重複的列值? – theking963

+0

重複的行。即,兩行之間的所有列都完全相同。 –

+0

在這一點上沒有,但它將來肯定有可能。 – theking963

0

這看起來是這樣的:

SELECT 
    IFNULL(t2.Col1, t1.Col1) Col1, 
    IFNULL(t2.Col2, t1.Col2) Col2, 
    IFNULL(t2.Col3, t1.Col3) Col3, 
    IFNULL(t2.Col4, t1.Col4) Col4, 
    'Add this string to the Last Column' 
FROM 
    Table1 t1 
    LEFT JOIN Table2 t2 ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2 
WHERE 
    t1.Column3 ='String' 
ORDER BY 
    Col4 

如果表2列可以在數據庫正常NULL值那麼這個選擇應該這樣開始:

SELECT 
    IF(t2.id is NULL, t1.Col1, t2.Col1) Col1, 
    IF(t2.id is NULL, t1.Col2, t2.Col2) Col1, 
    IF(t2.id is NULL, t1.Col3, t2.Col3) Col1, 
    IF(t2.id is NULL, t1.Col4, t2.Col4) Col1, 
    'Add this string to the Last Column' 
    . 
    . 
+0

它可能爲空和/或任何值。使用如果聽起來不是一個好主意。 – theking963

+0

@ daking963你爲什麼認爲IF不是一個好主意? – Karolis

+0

@ daking963如果您的查詢運行緩慢,這不是因爲IF,但這意味着您不構建最佳查詢邏輯和/或不使用最佳可能索引。這個查詢應該返回多少行? – Karolis