3

Patient&テーブルに200,000 行Personあり、表示されているクエリの実行には 30 秒かかります。

Personテーブル内PersonIdとテーブル内で主キー (およびクラスター化インデックス) を定義しPatientIdましたPatient。手順のパフォーマンスを向上させるために他に何ができますか?

データベース開発側の初心者。私は基本的な 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  
4

2 に答える 2

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

さらに、結合/フィルタリングする列を含むインデックスを使用して、テーブルにインデックスを作成する必要があります。

したがって、たとえば、列 (TenantId、PersonId、ResponsiblePersonId、AddedBy) が含まれる列 (PatientId、PatientIdentifier) を持つ表 Patient にインデックスを作成します。

于 2013-03-27T06:58:00.090 に答える
0

率直に言って、200,000 行は SQL サーバーにとっては何の意味もありません。

主キーがあるように、最初に論理の冗長性を削除してください。なぜまだ多くの列をグループ化するのか、同じテーブル (人) に 3 回参加する必要があるのはなぜですか?

論理の冗長性を取り除いた後、少なくとも複合インデックス/インクルード インデックスを作成する必要があります。実行計画を取得 (CTRL+M) または (CTRL+M) して、見逃したインデックスを確認します。さらにサポートが必要な場合は、数行のサンプル データを含むテーブル スキーマを貼り付けてください。

于 2013-03-27T07:07:45.097 に答える