可以说,我有我的MSSQL 2016(后来Azure的SQL)加入和组多个表
[ForumBoards] 1-n [ForumThreads] 1-n [ForumPosts] n-1 [Users]
这种关系我们有:50米板,20万个主题,100万发的帖子和50K用户
的目标现在是一个板内
- 有ID和名称所有电路板
- 一板内一些职位
- 最新张贴板
- 用户ID和最新帖子
的名字在我的首秀
SELECT
Boards.Id AS BoardsId,
Board.Name AS BoardsName,
LP.*
ThreadsCount = (SELECT Count(*) FROM ForumBoards AS SubB
JOIN ForumThreads AS SubT ON SubB.Id = SubT.BoardId
WHERE SubB.Id = Boards.Id AND SubT.BoardId = SubB.Id),
PostsCount = (SELECT Count(*) FROM ForumBoards AS SubB
JOIN ForumThreads AS SubT ON SubB.Id = SubT.BoardId
JOIN ForumPosts AS SubP ON SubT.Id = SubP.ThreadId
WHERE SubB.Id = Boards.Id AND SubT.BoardId = SubB.Id AND SubP.ThreadId = SubT.Id)
FROM ForumBoards as Boards
OUTER APPLY(
SELECT
TOP 1 SubP.Id AS LatestPostId,
SubP.PostedOn AS LatestPostPostedOn,
SubP.ThreadId AS LatestPostThreadId,
SubT.Topic AS LatestPostThreadTopic,
SubU.Id AS LatestPostUserId,
SubU.Username AS LatestPostUsername
FROM ForumBoards AS SubB
JOIN ForumThreads AS SubT ON SubB.Id = SubT.BoardId
JOIN ForumPosts AS SubP ON SubT.Id = SubP.ThreadId
JOIN Users AS SubU ON SubP.UserId = SubU.Id
WHERE SubB.Id = Boards.Id AND SubT.BoardId = SubB.Id AND SubP.ThreadId = SubT.Id AND SubU.Id = SubP.UserId
ORDER BY SubP.PostedOn DESC) AS LP
它有一个令人难以置信的糟糕表现。
没有
WHERE SubB.Id = Boards.Id AND SubT.BoardId = SubB.Id AND SubP.ThreadId = SubT.Id AND SubU.Id = SubP.UserId
它花费45ms,大约有6秒。
另一个节目是这样一个
SELECT
B.Id,
B.Name as BoardName,
Count(*) as ThreadsCount,
(SELECT Count(*)
FROM
ForumBoards Boards, ForumThreads Threads, ForumPosts Posts
WHERE Boards.Id = Threads.BoardId AND Threads.Id = Posts.ThreadId AND Boards.Id = B.Id) AS PostsCount
FROM ForumBoards B, ForumThreads T
WHERE B.Id = T.BoardId
GROUP BY B.Id, B.Name
这是确定的,约172ms - 但没有最新帖子。
但我认为我在对冲的错误一面。并提示我如何达到我的目标?
你已经创建非聚集索引在连接操作中使用的列(它也与相关查询有关)? – hastrb
@AliaksandrBortnik MSSQL query ex plan recommended to create CREATE NONCLUSTERED INDEX IX_ForumThreads_BoardRelation ON [dbo]。[ForumThreads]([BoardId])INCLUDE([Id])'完成了,是的。 – Ben
表中的ID是否有聚集索引? – hastrb