3

我有以下在 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
4

3 回答 3

1

我认为您遇到了相关的子查询问题。您正在试验的查询部分是 JOIN 条件的一部分,因此它会针对每个可能匹配的行进行全面评估。您正在让 SQL 引擎为 FROM 子句生成的每一行执行第二个“GROUP BY”。因此,它读取 2192 行来对 FROM 子句产生的每一行进行分组。

这表明您在 FROM 子句分组中获得 73 行 (2192 * 73 = 160 016)

当您将其更改为执行 SELECT 1 时,您消除了用于分组的表扫描读取。

于 2011-10-29T21:07:49.230 回答
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]
于 2011-10-29T21:48:30.663 回答
0

我想如果发现问题。
但我希望人们告诉我这是否确实是问题所在。
问题是 2 个子查询创建了某种类似临时表(不知道如何调用它)。
但是这 2 个临时表不包含 [FK_MovieID] 上的聚集索引。
因此,当外部连接尝试加入它们时,它需要多次扫描它们,这主要是问题所在。
现在如果我只能解决这个问题?

于 2011-10-29T23:10:35.903 回答