【发布时间】:2017-04-22 16:45:02
【问题描述】:
假设我在我的 MSSQL 2016(后来的 Azure SQL)上有这种关系
[ForumBoards] 1-n [ForumThreads] 1-n [ForumPosts] n-1 [Users]
我们有:50 个版块、20 万个线程、100 万个帖子和 5 万个用户
现在的目标是
- 所有带有 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
花费 45 毫秒,大约 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
没关系,大约 172 毫秒 - 但没有最新的帖子。
但我认为我在对冲的错误一边。并提示我如何实现目标?
【问题讨论】:
-
您是否已经在连接操作中使用的列上创建了非聚集索引(它也与相关查询有关)?
-
@AliaksandrBortnik MSSQL 查询计划建议创建
CREATE NONCLUSTERED INDEX IX_ForumThreads_BoardRelation ON [dbo].[ForumThreads] ([BoardId]) INCLUDE ([Id])已完成,是的。 -
表中的 ID 是否有聚集索引?
-
@AliaksandrBortnik 在所有 PK 上是的
-
您使用的是哪个 SQL 服务器?
标签: sql sql-server join sql-server-2016