我在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
答案 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),以查看您错过的索引。如果您需要进一步的帮助,请粘贴表格架构,其中包含几行示例数据。