1

この構造とインデックスを含むテーブルが1つあります

CREATE TABLE [dbo].[Report4](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Mesc] [nvarchar](50) NULL,
    [Line] [nvarchar](5) NULL,
    [Unit] [nvarchar](5) NULL,
    [Description] [nvarchar](500) NULL,
    [ST_CODE] [nvarchar](5) NULL,
    [PbsNo] [nvarchar](50) NULL,
    [PbsDate] [nvarchar](10) NULL,
    [PbsQty] [nvarchar](10) NULL,
    [PbsQtyRec] [nvarchar](10) NULL,
    [QtyConsum1] [nvarchar](10) NULL,
    [QtyConsum2] [nvarchar](10) NULL,
    [QtyConsum3] [nvarchar](10) NULL,
    [QtyConsum4] [nvarchar](10) NULL,
    [QtyConsum5] [nvarchar](10) NULL,
    [Type] [nvarchar](20) NULL,
    [InvQty] [nvarchar](10) NULL,
    [TypeRequest] [nvarchar](50) NULL,
    [HeaderId] [bigint] NULL,
    [LOCATION] [nvarchar](10) NULL,
 CONSTRAINT [PK_Report4] PRIMARY KEY CLUSTERED
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [HeaderId] ON [dbo].[Report4]
(
    [HeaderId] ASC
)
INCLUDE ( [Id],
[Mesc],
[Line],
[Unit],
[Description],
[ST_CODE],
[PbsNo],
[PbsDate],
[PbsQty],
[PbsQtyRec],
[QtyConsum1],
[QtyConsum2],
[QtyConsum3],
[QtyConsum4],
[QtyConsum5],
[Type],
[InvQty],
[TypeRequest]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [HeaderIdRAll] ON [dbo].[Report4]
(
    [HeaderId] ASC
)
INCLUDE ( [Id],
[Mesc],
[Line],
[Unit],
[Description],
[ST_CODE],
[PbsNo],
[PbsDate],
[PbsQty],
[PbsQtyRec],
[QtyConsum1],
[QtyConsum2],
[QtyConsum3],
[QtyConsum4],
[QtyConsum5],
[Type],
[InvQty],
[TypeRequest]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [LineNOIRHeaderId] ON [dbo].[Report4]
(
    [Line] ASC
)
INCLUDE ( [HeaderId])
WHERE ([line]='I')
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [LineNoRHeaderId] ON [dbo].[Report4]
(
    [Line] ASC
)
INCLUDE ( [HeaderId])
WHERE ([line]='H')
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [LineNoRMesc] ON [dbo].[Report4]
(
    [Line] ASC
)
INCLUDE ( [Mesc])
WHERE ([line]='I')
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [MescRAll] ON [dbo].[Report4]
(
    [Mesc] ASC
)
INCLUDE ( [Id],
[Line],
[Unit],
[Description],
[ST_CODE],
[PbsNo],
[PbsDate],
[PbsQty],
[PbsQtyRec],
[QtyConsum1],
[QtyConsum2],
[QtyConsum3],
[QtyConsum4],
[QtyConsum5],
[Type],
[InvQty],
[TypeRequest],
[HeaderId]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

このテーブルに対してこのクエリを実行したい

ALTER PROCEDURE [dbo].[SPSelectReport2] (@StringWhereParameter nvarchar(4000),@PageIndex int,@PageSize int )
AS
BEGIN

    SET NOCOUNT ON;

-- َ Begin Of Transaction
begin tran

declare @from int=(@PageSize*(@PageIndex-1))+1
declare @to int=(@PageIndex*@PageSize)

declare @Query nvarchar(max)
set @Query=' select 

distinct id, [Mesc], [Line]
      ,[Unit]
      ,[Discription]
      ,[InvQty]
      ,[LastDateNil]
      ,[StCode]
      ,[PlanCode]
      ,[MIN]
      ,[MAX]
      ,[LastDateConsum]
      ,[PbsNo]
      ,[PbsDate]
      ,[PbsQty]
      ,[PbsQtyRec]
      ,[DateDelay]
      ,[TypeRequest]
      ,[HeaderId]
      ,LOCATION
 from (

SELECT *, ROW_NUMBER() OVER(ORDER BY Id) ROW_NUM
  FROM(
((SELECT Id,[Mesc]
      ,[Line]
      ,[Unit]
      ,[Discription]
      ,[InvQty]
      ,[LastDateNil]
      ,[StCode]
      ,[PlanCode]
      ,[MIN]
      ,[MAX]
      ,[LastDateConsum]
      ,[PbsNo]
      ,[PbsDate]
      ,[PbsQty]
      ,[PbsQtyRec]
      ,[DateDelay]
      ,[TypeRequest]
      ,[HeaderId]
      ,LOCATION
  FROM [MyMaterialDB].[dbo].[Report2]
  WHERE headerid IN(SELECT HeaderId FROM [MyMaterialDB].[dbo].[Report2] WHERE line=''H'''+ @StringWhereParameter+'))
  UNION
  (
    (SELECT Id,[Mesc]
      ,[Line]
      ,[Unit]
      ,[Discription]
      ,[InvQty]
      ,[LastDateNil]
      ,[StCode]
      ,[PlanCode]
      ,[MIN]
      ,[MAX]
      ,[LastDateConsum]
      ,[PbsNo]
      ,[PbsDate]
      ,[PbsQty]
      ,[PbsQtyRec]
      ,[DateDelay]
      ,[TypeRequest]
      ,[HeaderId]
      ,LOCATION
  FROM [MyMaterialDB].[dbo].[Report2]
  WHERE mesc IN(SELECT mesc FROM [MyMaterialDB].[dbo].[Report2] WHERE line=''I''' +@StringWhereParameter+'))
  UNION
  (SELECT Id, [Mesc]
      ,[Line]
      ,[Unit]
      ,[Discription]
      ,[InvQty]
      ,[LastDateNil]
      ,[StCode]
      ,[PlanCode]
      ,[MIN]
      ,[MAX]
      ,[LastDateConsum]
      ,[PbsNo]
      ,[PbsDate]
      ,[PbsQty]
      ,[PbsQtyRec]
      ,[DateDelay]
      ,[TypeRequest]
      ,[HeaderId]
      ,LOCATION
  FROM [MyMaterialDB].[dbo].[Report2]
  WHERE mesc IN(SELECT HeaderId FROM [MyMaterialDB].[dbo].[Report2] WHERE line=''I'''+@StringWhereParameter+')
  )))) a)b where b.ROW_NUM between '+CAST(@from as varchar(10))+' and '+CAST(@to as varchar(10))

  -- Order by Mesc,Line,unit
 exec(@Query)
 --print @Query

--


 if @@error = 0    
 Commit Tran    
 Else   
 rollback tran
End

このテーブルに1000000を超えるレコードがあり、このspを実行すると、10分以上かかります。構造またはクエリを最適化するにはどうすればよいですか。私を助けてください。皆さんありがとう。

4

1 に答える 1

0

手始めに、次のことを行う必要があります(これらのアクションのみが、クエリの実行時間を1分未満に短縮できると思います)。

  • すべてを削除しますin clauseselect ... from ... where a in (select ...)a)非常に非常に遅い、b)SQLサーバーをメモリ不足で実行する可能性があるため(特にあなたのような大規模なデータセットの場合)、危険です。すべてのin句をに変更する必要がありますleft outer joins。これは非常に簡単です。
  • 削除しdistinct clauseます。これにより、クエリは(シェンの後ろで)順序付けを強制され、一般的にも非常に遅くなります。レコードがすでに区別されるように、クエリを言い換えてみてください
  • 個別のデータがある限り、に変更unionする必要がありますunion alldistinct unionユニオンは私の前のステートメントと同じです。使用union allすると、クエリが大幅に改善されます...データを区別する必要がないようにすることができる限り...

以前の3つの変更のうち少なくとも2つを行うことができれば、大幅な改善が見られると思います。それらすべてを処理できる場合は、非常に高速なクエリが実行されます。

また、sqlexecを「事前にコンパイルされた」ストアドプロシージャに変更する必要はありません。これを行うことで大幅な改善が得られるとは思いません(動的な場所があるので、どのような場合でもこれは適用されません)。

それがうまくいったかどうか教えてください。

于 2012-12-26T00:19:06.467 に答える