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''' [email protected]+')) 
    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'''[email protected]+') 
)))) 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 

運行此查詢到這個表我有更多的則百萬的記錄當運行這個sp時,它需要十分鐘或更長的時間。我如何優化結構或查詢。請幫幫我。謝謝大家。

+0

你爲什麼使用動態sql? 除[MyMaterialDB]中的數據外。[dbo]。[Report2]?這是一張桌子還是一張視圖? – WKordos

+0

我使用jqgrid插件我想實現搜索jqgrid。並在jqgrid實現搜索我只有一個解決方案,這個解決方案使用動態查詢。 Report2是MyMaterialDB中的表格 –

回答

0

對於初學者來說,你必須做到以下幾點(我認爲只有那些動作可以把你的查詢執行時間縮短到不到一分鐘多):

  • 刪除所有in clauseselect ... from ... where a in (select ...)是非常非常慢,b)危險,因爲它可以運行你的sql服務器內存不足 - 特別是像你這樣的大型數據集。您必須將所有條款更改爲left outer joins,這很容易做到。
  • 刪除distinct clause。這迫使你的查詢通過(在schenes後面)進行排序,並且通常也非常緩慢。嘗試這樣的記錄已經明顯
  • 只要你有不同的數據,你還必須更改unionunion all重組你的查詢。 Union與distinct union相同,與我以前的發言一致。如果你使用union all你會看到很大的改善您的查詢...只要你可以把你的數據是不同的,不需要...

如果你成功地使3以前的至少2變化,我想你會看到很大的改進。如果你可以處理所有這些,你將會有一個非常快的查詢。

而且也,不打擾改變你的SQL EXEC成「precompliled」存儲過程。我不認爲你將獲得由這樣的顯著改善(我看你有沒有動態哪來那麼這將不會在任何情況下申請人)。

請告訴我是否奏效。

+1

@ George Mavritsakis:謝謝你的幫助。 –