3

我在Patient & Person表中有200,000行,查詢顯示需要30秒才能執行。查詢處理200000條記錄的速度非常慢

我已經在表中PersonIdPatientIdPatient表中定義了主鍵(和聚簇索引)。我還可以在這裏做什麼來提高我的程序的性能?

數據庫開發方面的新手。我只知道基本的SQL。也不確定SQL Server能夠快速處理200,000行。

全動態過程,你可以在https://github.com/Padayappa/SQLProblem/blob/master/Performance

任何人看到處理面臨這樣巨大的行?我該如何提高績效?

DECLARE @return_value int, 
     @unitRows bigint, 
     @unitPages int, 
     @TenantId int, 
     @unitItems int, 
     @page int 
SET @TenantId = 1 
SET @unitItems = 20 
SET @page = 1 

DECLARE @PatientSearch TABLE(
    [PatientId] [bigint] NOT NULL, 
    [PatientIdentifier] [nvarchar](50) NULL, 
    [PersonNumber] [nvarchar](20) NULL, 
    [FirstName] [nvarchar](100) NOT NULL, 
    [LastName] [nvarchar](100) NOT NULL, 
    [ResFirstName] [nvarchar](100) NOT NULL, 
    [ResLastName] [nvarchar](100) NOT NULL, 
    [AddFirstName] [nvarchar](100) NOT NULL, 
    [AddLastName] [nvarchar](100) NOT NULL, 
    [Address] [nvarchar](255) NULL, 
    [City] [nvarchar](50) NULL, 
    [State] [nvarchar](50) NULL, 
    [ZipCode] [nvarchar](20) NULL, 
    [Country] [nvarchar](50) NULL, 
    [RowNumber] [bigint] NULL 
    ) 

    INSERT INTO @PatientSearch SELECT PAT.PatientId 
    ,PAT.PatientIdentifier  
    ,PER.PersonNumber 
    ,PER.FirstName 
    ,PER.LastName 
    ,RES_PER.FirstName AS ResFirstName 
    ,RES_PER.LastName AS ResLastName 
    ,ADD_PER.FirstName AS AddFirstName 
    ,ADD_PER.LastName AS AddLastName 
    ,PER.Address 
    ,PER.City 
    ,PER.State 
    ,PER.ZipCode 
    ,PER.Country 
    ,ROW_NUMBER() OVER (ORDER BY PAT.PatientId DESC) AS RowNumber 
    FROM dbo.Patient AS PAT 
    INNER JOIN dbo.Person AS PER 
    ON PAT.PersonId = PER.PersonId 
    INNER JOIN dbo.Person AS RES_PER 
      ON PAT.ResponsiblePersonId = RES_PER.PersonId 
    INNER JOIN dbo.Person AS ADD_PER 
      ON PAT.AddedBy = ADD_PER.PersonId 
    INNER JOIN dbo.Booking AS B 
      ON PAT.PatientId = B.PatientId 

    WHERE PAT.TenantId = @TenantId AND B.CategoryId = @CategoryId 

    GROUP BY PAT.PatientId 
    ,PAT.PatientIdentifier  
    ,PER.PersonNumber 
    ,PER.FirstName 
    ,PER.LastName 
    ,RES_PER.FirstName 
    ,RES_PER.LastName 
    ,ADD_PER.FirstName 
    ,ADD_PER.LastName 
    ,PER.Address 
    ,PER.City 
    ,PER.State 
    ,PER.ZipCode 
    ,PER.Country  

    ; 

    SELECT @unitRows = @@ROWCOUNT 
    ,@unitPages = (@unitRows/@unitItems) + 1; 

    SELECT * 
    FROM @PatientSearch AS IT 
    WHERE RowNumber BETWEEN (@page - 1) * @unitItems + 1 AND @unitItems * @page 
+0

你插入你的表變量有多少行?您最好創建一個實際的臨時表('#PatientSearch')。原因在於查詢優化器總是會假定一個表變量只有一行(它缺少任何統計信息),因此如果將大量行插入表變量 – 2013-03-27 07:00:05

+0

@marc_s,它實際上會插入所有200000行爲空搜索:( – Billa 2013-03-27 07:01:13

+0

***爲什麼***你需要將所有200'000行復制到臨時表中才能開始?不能只在實際數據上定義一個CTE,並添加' ROW_NUMBER()'函數,並用它來選擇你的數據 – 2013-03-27 07:02:44

回答

3

好了,除非我失去了一些東西(如重複行?),你應該能夠去除GROUP BY

GROUP BY PAT.PatientId 
    ,PAT.PatientIdentifier  
    ,PER.PersonNumber 
    ,PER.FirstName 
    ,PER.LastName 
    ,RES_PER.FirstName 
    ,RES_PER.LastName 
    ,ADD_PER.FirstName 
    ,ADD_PER.LastName 
    ,PER.Address 
    ,PER.City 
    ,PER.State 
    ,PER.ZipCode 
    ,PER.Country  

因爲你是在選擇列表中的所有字段分組,和你分區除PAT.PatientId

此外,您應該create index在索引中包含您加入/過濾的列的表。

因此,例如,我會創建

+0

我有一個重複的記錄,因爲病人有更多的沒有預訂。我現在更新了我的查詢。它是一個動態搜索查詢。請檢查 – Billa 2013-03-27 07:03:02

+0

整個過程是在https://github.com/Padayappa/SQLProblem/blob/master/Performance – Billa 2013-03-27 07:10:08

+0

'CREATE非聚集索引IX_NC_PatientSearch ON dbo.Patient(TenantId,PERSONID,ResponsiblePersonId,AddedBy) 包括:(PatientId,PatientIdentifier )'產生相同的結果。現在它又增加了5秒:( – Billa 2013-03-27 08:25:31

0

老實說與包含的列(PatientId,PatientIdentifier)列(TenantId,PERSONID,ResponsiblePersonId,AddedBy)上表患者索引,200,000行沒什麼到SQL Server。

請首先刪除邏輯冗餘,就像你有主鍵一樣,爲什麼還要組這麼多列,爲什麼你需要加入同一個表(人)3次?

刪除邏輯冗餘後,您至少需要創建一些複合索引/包含索引。獲取執行計劃(CTRL + M)或(CTRL + M),查看錯過的索引。如果您需要進一步的幫助,請將表格模式粘貼幾行樣本數據。

+0

1 join給我Patient First Name,2 join for添加人名First,3rd加入負責任的醫生名字 – Billa 2013-03-27 07:09:03