2016-08-04 57 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