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

0

問題が見つかったらと思います。
しかし、これが本当に問題なのかどうか、人々に教えてもらいたいです。
問題は、2 つのサブクエリが一時テーブルのようなものを作成することです (呼び出し方がわからない)。
ただし、これら 2 つの一時テーブルには [FK_MovieID] のクラスター化インデックスが含まれていません。
そのため、外部結合が結合しようとすると、それらを数回スキャンする必要があり、これが主な問題です。
今私はこれを修正することができますか?

于 2011-10-29T23:10:35.903 に答える
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 に答える