我有以下在SQL Server CE 4上运行的SQL查询
SELECT [Join_ReleaseMinDatePost].[FK_MovieID]
FROM (
SELECT [FK_MovieID], MIN([DatePost]) AS [ReleaseMinDatePost]
FROM [Release]
GROUP BY [FK_MovieID]
) [Join_ReleaseMinDatePost]
INNER JOIN
(
SELECT COUNT([ID]) AS [FolderCount], [FK_MovieID]
FROM [MovieFolder]
GROUP BY [FK_MovieID]
) [Join_MovieFolder]
ON [Join_MovieFolder].[FK_MovieID] = [Join_ReleaseMinDatePost].[FK_MovieID]
此查询需要很长时间才能执行,但如果我更改了部件
SELECT COUNT([ID]) AS [FolderCount], [FK_MovieID] FROM [MovieFolder] GROUP BY [FK_MovieID]
到
SELECT 1 AS [FolderCount], [FK_MovieID] FROM [MovieFolder]
所以完整的查询变为
SELECT [Join_ReleaseMinDatePost].[FK_MovieID]
FROM ( SELECT [FK_MovieID], MIN([DatePost]) AS [ReleaseMinDatePost] FROM [Release] GROUP BY [FK_MovieID] ) [Join_ReleaseMinDatePost]
INNER JOIN (SELECT 1 AS [FolderCount], [FK_MovieID] FROM [MovieFolder] ) [Join_MovieFolder]
ON [Join_MovieFolder].[FK_MovieID] = [Join_ReleaseMinDatePost].[FK_MovieID]
然后表现变得非常快
问题是如果自己采取的部分变化非常快。但由于某种原因,第一个查询的执行计划显示索引扫描中的“实际行数”为160,016,而表MovieFolder中的总行数为2,192。
并且“估计行数”是2,192
所以我认为问题在于行数,但我无法弄清楚为什么它们都搞砸了。
任何帮助将不胜感激 :)
感谢
表的架构如下
CREATE TABLE [Release] (
[ID] int NOT NULL
, [FD_ForumID] int NOT NULL
, [FK_MovieID] int NULL
, [DatePost] datetime NULL
);
GO
ALTER TABLE [Release] ADD CONSTRAINT [PK__Release__0000000000000052] PRIMARY KEY ([ID]);
GO
CREATE INDEX [IX_Release_DatePost] ON [Release] ([DatePost] ASC);
GO
CREATE INDEX [IX_Release_FD_ForumID] ON [Release] ([FD_ForumID] ASC);
GO
CREATE INDEX [IX_Release_FK_MovieID] ON [Release] ([FK_MovieID] ASC);
GO
CREATE UNIQUE INDEX [UQ__Release__0000000000000057] ON [Release] ([ID] ASC);
GO
CREATE TABLE [MovieFolder] (
[ID] int NOT NULL IDENTITY (1,1)
, [Path] nvarchar(500) NOT NULL
, [FK_MovieID] int NULL
, [Seen] bit NULL
);
GO
ALTER TABLE [MovieFolder] ADD CONSTRAINT [PK_MovieFolder] PRIMARY KEY ([ID]);
GO
CREATE INDEX [IX_MovieFolder_FK_MovieID] ON [MovieFolder] ([FK_MovieID] ASC);
GO
CREATE INDEX [IX_MovieFolder_Seen] ON [MovieFolder] ([Seen] ASC);
GO
CREATE UNIQUE INDEX [UQ__MovieFolder__0000000000000019] ON [MovieFolder] ([ID] ASC);
GO
CREATE UNIQUE INDEX [UQ__MovieFolder__0000000000000020] ON [MovieFolder] ([Path] ASC);
GO
答案 0 :(得分:1)
我认为你遇到了correlated subquery问题。您正在尝试的查询部分是JOIN条件的一部分,因此对每个可能匹配的行进行完全评估。您正在使您的SQL引擎为FROM子句生成的每一行执行第二个“GROUP BY”。所以它正在读取2192行来为FROM子句生成的每一行执行group by。
这表明你在FROM子句分组中得到73行(2192 * 73 = 160 016)
当您将其更改为执行SELECT 1时,您将删除用于分组的表扫描读取。
答案 1 :(得分:0)
DaveE对你的相关子查询的问题是正确的。出现这些问题时,您经常需要重新考虑整个查询。如果还有其他任何问题,您可以节省将子查询提取到临时表的时间,如下所示:
/* Declare in-memory temp table */
DECLARE @Join_MovieFolder TABLE (
count INT,
movieId INT )
/* Insert data into temp table */
INSERT INTO @Join_MovieFolder ( count, movieId )
SELECT COUNT([ID]) AS [FolderCount], [FK_MovieID]
FROM [MovieFolder]
GROUP BY [FK_MovieID]
/* Inner join the temp table to avoid excessive sub-quering */
SELECT [Join_ReleaseMinDatePost].[FK_MovieID]
FROM (
SELECT [FK_MovieID], MIN([DatePost]) AS [ReleaseMinDatePost]
FROM [Release]
GROUP BY [FK_MovieID]
) [Join_ReleaseMinDatePost]
INNER JOIN @Join_MovieFolder
ON @Join_MovieFolder.movieId = [Join_ReleaseMinDatePost].[FK_MovieID]
答案 2 :(得分:0)
我认为如果发现问题。
但我希望有人告诉我这是否确实存在问题
问题是2个子查询创建了某种类似临时表(不知道如何调用它)
但是这两个临时表在[FK_MovieID]上不包含聚簇索引
因此,当外部联接尝试加入它们时,需要多次扫描它们,这主要是问题所在
现在,如果我只能解决这个问题?