【发布时间】:2013-03-27 06:54:35
【问题描述】:
Patient & Person 表中有 200,000 行,显示的查询需要 30 秒才能执行。
我已经在PersonId 的Person 表和Patient 表的PatientId 上定义了主键(和聚集索引)。我还能在这里做些什么来提高我的程序的性能?
数据库开发方面的新手。我只知道基本的 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
【问题讨论】:
-
您在表变量中插入了多少行?您最好创建一个实际的临时表 (
#PatientSearch)。原因是查询优化器总是假设一个表变量只有一行(它没有任何统计信息),因此如果你在一个表变量中插入很多行,性能会非常糟糕 -
@marc_s,它实际上为空搜索插入了所有 200000 行:(
-
为什么您需要将所有 200'000 行复制到临时表中吗?难道你不能在你的实际数据之上定义一个 CTE,然后向它添加
ROW_NUMBER()函数,然后用它来选择你的数据吗?? -
顺便说一句:200'000 行无论如何都不是 huge ......如果你说的是 2000 亿行 -那么是的,那将是一个大小适中的数据库。
-
@marc_s, REAL Temp 表意思是
CREATE Table #PatientSearch而不是DECLARE @patientsearch as Table?
标签: sql sql-server sql-server-2008 sql-server-2005 azure-sql-database