如何修复 SQL Server Compact Edition 4 上的查询性能
我有以下在 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
i have the following SQL Query which runs on SQL Server CE 4
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]
this query takes a long time to execute but if i change the Part
SELECT COUNT([ID]) AS [FolderCount], [FK_MovieID] FROM [MovieFolder] GROUP BY [FK_MovieID]
To
SELECT 1 AS [FolderCount], [FK_MovieID] FROM [MovieFolder]
So the full query becomes
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]
then the performance becomes very fast.
the problem is that the part that was changed if taken by itself is pretty fast. but for some reason the execution plan of the first query shows that the "actual number of rows" in the index scan is 160,016 while the total number of rows in the table MovieFolder is 2,192.
and the "Estimated number of rows" is 2,192.
so i think the problem is in the number of rows but i cant figure out why its all messed up.
any help will be appreciated :)
thanks
the schema of the tables is below
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您遇到了相关子查询问题。您正在试验的查询部分是 JOIN 条件的一部分,因此它会针对每个潜在匹配行进行全面评估。您让 SQL 引擎对 FROM 子句生成的每一行执行第二个“GROUP BY”。因此它读取 2192 行来对 FROM 子句生成的每一行进行分组。
这表明您在 FROM 子句分组中获得了 73 行 (2192 * 73 = 160 016)
当您将其更改为执行 SELECT 1 时,您消除了分组的表扫描读取。
I think you're running into a correlated subquery problem. The query part you're experimenting with is part of a JOIN condition, so it is fully evaluated for every potentially matching row. You're making your SQL engine do the second 'GROUP BY' for every row produced by the FROM clause. So it's reading 2192 rows to do the group by for each and every row produced by the FROM clause.
This suggest you're getting 73 rows in the FROM clause grouping (2192 * 73 = 160 016)
When you change it to do SELECT 1, you eliminate the table-scan read for grouping.
DaveE 关于相关子查询的问题是正确的。当出现这些问题时,您通常需要重新考虑整个查询。如果出现其他问题,您可能可以节省时间,将子查询提取到临时表中,如下所示:
DaveE is right about the issue with your correlated subquery. When these issues arise you often need to rethink your entire query. If anything else fails you can probably save time extracting your sub-query to a temporary table like this:
我想如果发现问题了。
但我希望人们告诉我这是否确实是问题所在。
问题是这两个子查询创建了某种类似临时表的东西(不知道如何调用它)。
但这 2 个临时表不包含 [FK_MovieID] 上的聚集索引。
因此,当外部联接尝试加入它们时,它需要多次扫描它们,这主要是问题所在。
现在我是否只能解决这个问题?
i think if found the problem.
but i would like people to tell me if this indeed the problem.
the problem is that the 2 sub queries create some kind of like temp table (dont know how to call it).
but these 2 temp table dont contain a clustered index on [FK_MovieID].
so when the external join tries to join them it need to scan them several times and and this is mainly the problem.
now if i can only fix this ?