优化来自多个表的连接
如何优化下面提到的查询性能如所示的表结构在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
这是一种不同的方法时。我不能说性能的提高,因为这取决于很多其他的事情,但我相信它是一个相当的版本,更容易阅读。
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;
你应该试试这个请求:
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个表添加一些索引。
查询执行得很好,索引后结果更好。感谢代码。 –
问题是你想要优化..可读性(和可维护性)和/或性能?
大多数人在撰写查询时都有自己的'风格'。我更喜欢下面的那个,但是对于服务器来说,它可能看起来是一样的,并且很有可能系统将获得相同数量的“工作”来获取数据,尽管它看起来与我们人类不同。我会建议谷歌一点点,并学习如何解释查询计划。
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
在我注意的事情是,你同时通过CompanyID
和OutletID
作为过滤器的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
指数使其工作做得更好。
我试图实现性能,因为记录方式太多了,可维护性在这里不太重要。不过,我尝试了上面的答案中提到的代码,因为它与你的相同。感谢代码和帮助。 –
好吧,'重新格式化'代码只会产生较小的影响;但是这些指标应该会有相当大的改进。祝你好运! – deroby
编辑您的问题以包含样本数据和期望的结果将有助于他人理解您的查询应该做什么。 –
如果tt.Locale的值范围很小,您可以为其创建一个字典表并在where子句中使用外键 - 对varchar数据的搜索很慢。此外,您在两个子问题中的where子句都非常相似 - 请考虑是否可以将其移至外部查询而不是执行两次相同的操作。 – PacoDePaco