2016-08-04 191 views
2

如何優化下面提到的查詢性能如所示的表結構在PIC下面優化來自多個表的連接

Pic Showing The Table Structure

select CounterID, OutletTitle, CounterTitle 
from(
    select OutletID, Text as OutletTitle 
    from Outlets as q1 
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID 
    where tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8 --Locale & CompanyID & OutletID 
    ) as O  
inner join  
(
    select CounterID, Text as CounterTitle, OutletID 
    from Counters as q1 
    inner join 
    TranslationTexts as tt 
    on q1.TitleID=tt.TranslationID 
    where tt.Locale='ar-SA' and q1.OutletID=8 --Locale & OutletID 
) as C 
on O.OutletID=C.OutletID 
+0

編輯您的問題以包含樣本數據和期望的結果將有助於他人理解您的查詢應該做什麼。 –

+0

如果tt.Locale的值範圍很小,您可以爲其創建一個字典表並在where子句中使用外鍵 - 對varchar數據的搜索很慢。此外,您在兩個子問題中的where子句都非常相似 - 請考慮是否可以將其移至外部查詢而不是執行兩次相同的操作。 – PacoDePaco

回答

1

這是一種不同的方法時。我不能說性能的提高,因爲這取決於很多其他的事情,但我相信它是一個相當的版本,更容易閱讀。

SELECT 
    C.CounterID 
    , tt.Text AS OutletTitle 
    , tt.Text AS CounterTitle 
FROM 
    Outlets AS q1 
    INNER JOIN TranslationTexts AS tt ON q1.TitleID=tt.TranslationID 
    INNER JOIN Counters C ON c.OutletID=q1.OutletID 
    INNER JOIN TranslationTexts AS tt2 ON tt2.TranslationID=tt.TranslationID AND tt2.Locale=tt.Locale 
WHERE 
    tt.Locale='ar-SA' and q1.CompanyID=311 and q1.OutletID=8; 
2

你應該試試這個請求:

SELECT CounterID, tou.Text as OutletTitle, tco.Text as CounterTitle 
FROM Counters as co 
    INNER JOIN Outlets as ou ON co.OutletID = ou.OutletID 
    INNER JOIN TranslationTexts as tco on co.TitleID=tco.TranslationID 
    INNER JOIN TranslationTexts as tou on ou.TitleID=tou.TranslationID 
WHERE co.CompanyID=311 and co.OutletID=8 AND tco.Locale='ar-SA' and tou.Locale='ar-SA' 

爲了有更好的性能,可以在3個表添加一些索引。

+0

查詢執行得很好,索引後結果更好。感謝代碼。 –

1

問題是你想要優化..可讀性(和可維護性)和/或性能?

大多數人在撰寫查詢時都有自己的'風格'。我更喜歡下面的那個,但是對於服務器來說,它可能看起來是一樣的,並且很有可能系統將獲得相同數量的「工作」來獲取數據,儘管它看起來與我們人類不同。我會建議谷歌一點點,並學習如何解釋查詢計劃。

SELECT q2.CounterID, 
     tt1.Text as OutletTitle, 
     tt2.Text as CounterTitle 

FROM Outlets as q1 

INNER JOIN Counters as q2 
     ON q2.OutletID = q1.OutletID 

INNER JOIN TranslationTexts as tt1 
     ON tt1.TranslationID = q1.TitleID 
     AND tt1.Locale  = 'ar-SA' 

INNER JOIN TranslationTexts as tt2 
     ON tt2.TranslationID = q2.TitleID 
     AND tt2.Locale  = 'ar-SA' 

WHERE q1.CompanyID = 311 
    AND q1.OutletID = 8 

在我注意的事情是,你同時通過CompanyIDOutletID作爲過濾器的Outlets表。由於OutletID是該表的主要關鍵,我想知道您是否真的需要CompanyID上的過濾器。最好它會消除記錄,因爲它是錯誤的公司,但不知何故,我的印象是,你已經知道正確的CompanyID

至於性能,我想勸告這些指標

CREATE INDEX idx_Locale ON TranslationTexts (Locale, Translation_id) 
CREATE INDEX idx_CompanyID ON Outlets (CompanyID) INCLUDE (TitleID, OutletID) 

最有可能的,你甚至可以使指數Local一個UNIQUE指數使其工作做得更好。

+0

我試圖實現性能,因爲記錄方式太多了,可維護性在這裏不太重要。不過,我嘗試了上面的答案中提到的代碼,因爲它與你的相同。感謝代碼和幫助。 –

+0

好吧,'重新格式化'代碼只會產生較小的影響;但是這些指標應該會有相當大的改進。祝你好運! – deroby