处理200000多条记录的查询速度非常慢

时间:2013-03-27 06:54:35

标签: sql sql-server sql-server-2008 sql-server-2005 azure-sql-database

我在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  

2 个答案:

答案 0 :(得分: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

因此,例如,我会在表格Patient上创建一个索引,其中列(TenantId,PersonId,ResponsiblePersonId,AddedBy)包含列(PatientId,PatientIdentifier)

答案 1 :(得分:0)

坦率地说,200,000行对SQL服务器来说没什么。

请先删除逻辑冗余,就像你有主键,为什么还要分组这么多列,为什么你需要加入同一个表(人)3次?

删除逻辑冗余后,至少需要创建一些复合索引/包含索引。获取执行计划(CTRL + M)或(CTRL + M),以查看您错过的索引。如果您需要进一步的帮助,请粘贴表格架构,其中包含几行示例数据。