[英]SQL Query Performance Optimization
我有以下SQL,它返回349017条记录。 记录数量每天都会增加。
目前,我使用分页仅显示12条记录。 每12条记录返回大约2到3秒。 如何将查询优化为0秒? 请给出任何解决方案/建议。
我有很多图像数据将在应用程序中显示。 用户滚动时,必须根据此查询快速加载图像。
SELECT
vInfo.UserId
,vInfo.VehicleInfoId
,vImage.GuidedTourTemplateId
,vImage.VehicleImageId
,vInfo.Value AS VehicleName
,vInfo.Value AS ImageName
,Prop.PropertyId
,COALESCE(Loc.LocationName, 'NA') AS VehicleLocation
,Prop.PropertyName
,vImage.Latitude
,vImage.Longitude
,vImage.IsMain
,CASE
WHEN (DATEADD(DAY, tPlan.BackupDays, CAST(vImage.CreatedDate AS DATETIME)) > (GETDATE()))
THEN 1
ELSE 0
END AS IsAccess
,vImage.ImageURL
,vImage.ThumbImageURL
,CASE
WHEN vImage.AudioURL <> ''
THEN 1
ELSE 0
END AS IsAudio
,vImage.AudioURL
,CASE
WHEN vImage.Comments <> ''
THEN 1
ELSE 0
END AS IsComment
,vImage.Comments
,COALESCE(DImage.Damaged, 0) AS IsDamaged
,tImage.TotalAdditionalImages
,CONVERT(VARCHAR(12), CAST(vInfo.CreatedDate AS DATETIME), 107) AS CreateDate
,vInfo.EditDate
,0 AS RowNumber
FROM
[dbo].[VehicleInfo] vInfo
INNER JOIN
[dbo].[Property] Prop ON Prop.PropertyId = vInfo.PropertyId
INNER JOIN
[dbo].[Location] Loc ON Loc.LocationId = vInfo.LocationId
INNER JOIN
[dbo].[VehicleImage] vImage ON vInfo.VehicleInfoId = vImage.VehicleInfoId
INNER JOIN
[dbo].[PropertyPlan] tPropPlan ON vImage.PropertyId = tPropPlan.PropertyId
INNER JOIN
[dbo].[PlanType] tPlan ON tPropPlan.PlanTypeId = tPlan.PlanTypeId
OUTER APPLY
(SELECT COUNT(VehicleInfoId) AS TotalAdditionalImages
FROM [dbo].[VehicleImage]
WHERE VehicleInfoId = vInfo.VehicleInfoId) tImage
OUTER APPLY
(SELECT
CASE
WHEN COUNT(VehicleInfoId) > 0
THEN 1
ELSE 0
END AS Damaged
FROM [dbo].[DamagedVehicleImage]
WHERE VehicleInfoId = vInfo.VehicleInfoId) DImage
WHERE
vInfo.TenantId = '72c79d03-6692-4813-8c5a-4649cb34ca2f'
AND Prop.DeleteStatus = 0
AND vImage.IsMain = 1
ORDER BY
CAST(vInfo.CreatedDate AS DATETIME) DESC
,Prop.PropertyName
OFFSET 0 ROWS
FETCH NEXT 12 ROWS ONLY
执行计划
没有模式和示例数据,这只是一个猜测,但是看起来
ORDER BY
CAST(vInfo.CreatedDate AS DATETIME) DESC
是最大的时间浪费。
理想情况下,您不会将日期存储为datetime以外的其他内容-我猜您将需要在更多位置对createdData进行排序。
如果您不能修改数据类型,则可以创建基于函数的索引来减轻CAST操作的负担(今天几乎可以肯定没有对它进行索引)。
解决方案非常简单-您应该将vInfo.CreatedDate
作为索引DATETIME列。
如果由于某种原因无法修改列类型,则可以创建一个PERSISTENT
计算列 ,然后在其上定义一个索引。
例:
ALTER TABLE dbo.vInfo
ADD _CreatedDateAsDateTime AS CONVERT(DATETIME, CreatedDate) PERSISTED;
CREATE INDEX [IX_...] ON dbo.vInfo(_CreatedDateAsDateTime) INCLUDE(...);
ALTER TABLE dbo.VehicleInfo
ADD CreatedDate2 AS CONVERT(DATETIME, CreatedDate)
GO
CREATE UNIQUE NONCLUSTERED INDEX ix
ON dbo.VehicleInfo (CreatedDate2 DESC, PropertyId, TenantId)
--INCLUDE (UserId, VehicleInfoId, Value, LocationId, EditDate)
--WHERE TenantId = '72c79d03-6692-4813-8c5a-4649cb34ca2f'
GO
SELECT
vInfo.UserId
, vInfo.VehicleInfoId
, vImage.GuidedTourTemplateId
, vImage.VehicleImageId
, VehicleName = vInfo.Value
, ImageName = vInfo.Value
, Prop.PropertyId
, VehicleLocation = ISNULL(Loc.LocationName, 'NA')
, Prop.PropertyName
, vImage.Latitude
, vImage.Longitude
, vImage.IsMain
, IsAccess = IIF(DATEADD(DAY, tPlan.BackupDays, CAST(vImage.CreatedDate AS DATETIME)) > GETDATE(), 1, 0)
, vImage.ImageURL
, vImage.ThumbImageURL
, IsAudio = IIF(vImage.AudioURL <> '', 1, 0)
, vImage.AudioURL
, IsComment = IIF(vImage.Comments <> '', 1, 0)
, vImage.Comments
, IsDamaged =
CASE WHEN
EXISTS(
SELECT 1
FROM DamagedVehicleImage i2
WHERE i2.VehicleInfoId = vInfo.VehicleInfoId
)
THEN 1
ELSE 0
END
, TotalAdditionalImages = COUNT(vImage.VehicleInfoId) OVER (PARTITION BY vImage.VehicleInfoId)
, CONVERT(VARCHAR(12), CreatedDate2, 107) AS CreateDate
, vInfo.EditDate
, 0 AS RowNumber
FROM dbo.VehicleInfo vInfo
JOIN dbo.Property Prop ON Prop.PropertyId = vInfo.PropertyId
JOIN dbo.Location Loc ON Loc.LocationId = vInfo.LocationId
JOIN dbo.VehicleImage vImage ON vInfo.VehicleInfoId = vImage.VehicleInfoId
JOIN dbo.PropertyPlan tPropPlan ON vImage.PropertyId = tPropPlan.PropertyId
JOIN dbo.PlanType tPlan ON tPropPlan.PlanTypeId = tPlan.PlanTypeId
WHERE vInfo.TenantId = '72c79d03-6692-4813-8c5a-4649cb34ca2f'
AND Prop.DeleteStatus = 0
AND vImage.IsMain = 1
ORDER BY
CreatedDate2 DESC
, Prop.PropertyName
OFFSET 0 ROWS FETCH NEXT 12 ROWS ONLY
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.