2011-10-29 8 views
3

私のSQL Server CE上で動作し、次のSQLクエリを持っている4SQL Serverでこのクエリのパフォーマンスを修正する方法Compact Editionの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] 

このクエリの実行に時間がかかるが、私はパートを変更した場合

SELECT 1 AS [FolderCount], [FK_MovieID] FROM [MovieFolder] 

SELECT COUNT([ID]) AS [FolderCount], [FK_MovieID] FROM [MovieFolder] GROUP BY [FK_MovieID] 

だから、完全なクエリが

なり、

パフォーマンスが非常に高速になります。
問題は、それだけで撮影した場合に変更された部分がかなり速いことです。何らかの理由で最初のクエリの実行計画では、インデックススキャンの「実際の行数」が160,016であり、MovieFolderテーブルの行の合計数は2,192であることが示されています。 、「推定行数」は2,192です。
私は問題が行の数にあると思うが、なぜそれがすべて乱れているのか理解できない。
任意の助けが理解されるであろう:)テーブルの おかげ

スキーマは、私はあなたがcorrelated subquery問題に実行していると思う

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

クエリの目的は何ですか?なぜあなたは何のためにカウントを使用していないときに、各映画のカウントのリストを内部に参加する必要がありますか? – Alex

+0

これは大きなクエリの一部ですが、私は減速を作り出していた部分を分離し、他の人がそれを理解できないようにしました:) – Karim

+0

あなたはSELECTを "SELECT [Join_ReleaseMinDatePost]に変更できます。[FK_MovieID]、[ReleaseMinDatePost]、[FolderCount] "より意味が分かります:) – Karim

答えて

1

を下回っています。実験中のクエリ部分はJOIN条件の一部なので、一致する可能性のあるごとに完全に評価されます。行あなたは、FROM句によって生成されたすべての行に対して、SQLエンジンを2番目の「GROUP BY」にします。したがって、FROM句によって生成された各行ごとにグループを実行するのは2192行です。

これは、あなたがFROM句のグループ化(2192 * 73 = 160 016)

あなたはそれを変更

は1を選択しますするには73行を取得している提案は、グループ化のために読んでテーブル・スキャンを排除します。

+0

この問題はSQL Serverのコンパクト版にのみ存在し、大きな問題ではないと思いますしかし、確かに – Karim

+0

私はなぜ、 "SELECT 1、[FK_MovieID] FROM [MovieFolder]"テーブルスキャンを排除するのか理解していない、それはFK_MovieIDテーブルから考える必要があると思う。 – Karim

+0

私はcorreltaedサブクエリについて読んで、このクエリは、メインクエリの任意の項目へのanyreferenceを含んでいないので、このクエリは相関関係にあると思います。また、SQL Serverのコンパクトエディションは相関サブクエリをサポートしません。 – Karim

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] 
+0

私はSQL Serverのコンパクト版で知っている限り、一時的なテーブルはありません。 – Karim

+0

ああ... CEの部分を逃した。いいえ、それはあなたのためのオプションはありません。ごめんなさい。私はあなたがサブクエリなしであなたのクエリを作成できるかどうかを検討することをお勧めします... – Alex

+0

とにかくおかげで:) – Karim

0

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

関連する問題