Performance Sql存储过程在记录不断增加的情况下需要更多的时间来执行,有什么方法可以优化它吗
我有60万条记录,我想从中提取10条记录,因为我想在网格中只显示10条记录。当我提取1-10000条记录时,我的存储过程工作正常,例如500-510。之后,当行号增加时,执行时间增加,例如,如果我提取记录b/w 1,00000-1,00010,则需要更多时间执行时间 有谁能帮我一下吗?我用ROW_NUMBER来获取数字ROW NUMBER,用between来检索数据 请给出获取记录的优化方法 存储过程创建一个sql查询,如下所示Performance Sql存储过程在记录不断增加的情况下需要更多的时间来执行,有什么方法可以优化它吗,performance,sql-server-2008,Performance,Sql Server 2008,我有60万条记录,我想从中提取10条记录,因为我想在网格中只显示10条记录。当我提取1-10000条记录时,我的存储过程工作正常,例如500-510。之后,当行号增加时,执行时间增加,例如,如果我提取记录b/w 1,00000-1,00010,则需要更多时间执行时间 有谁能帮我一下吗?我用ROW_NUMBER来获取数字ROW NUMBER,用between来检索数据 请给出获取记录的优化方法 存储过程创建一个sql查询,如下所示 SELECT FuelClaimId from
SELECT FuelClaimId from
( SELECT fc.FuelClaimId,ROW_NUMBER() OVER ( order by fc.FuelClaimId ) AS RowNum
from FuelClaims fc
INNER JOIN Vehicles v on fc.VehicleId =v.VehicleId
INNER JOIN Drivers d on d.DriverId =v.OfficialID
INNER JOIN Departments de on de.DepartmentId =d.DepartmentId
INNER JOIN Provinces p on de.ProvinceId =p.ProvinceId
INNER JOIN FuelRates f on f.FuelRateId =fc.FuelRateId
INNER JOIN FuelClaimStatuses fs on fs.FuelClaimStatusId= fc.statusid
INNER JOIN LogsheetMonths l on l.LogsheetMonthId =f.LogsheetMonthId
Where fc.IsDeleted = 0) AS MyDerivedTable WHERE MyDerivedTable.RowNum BETWEEN
600000 And 600010
我有60万条记录,我想从中提取10条记录,因为我想在网格中只显示10条记录。当我提取1-10000条记录时,我的存储过程工作正常,例如500-510。之后,当行号增加时,执行时间增加,例如,如果我提取记录b/w 1,00000-1,00010,则需要更多时间执行时间
有谁能帮我一下吗?我用ROW_NUMBER来获取数字ROW NUMBER,用between来检索数据
请给出获取记录的优化方法
存储过程创建一个sql查询,如下所示
SELECT FuelClaimId from
( SELECT fc.FuelClaimId,ROW_NUMBER() OVER ( order by fc.FuelClaimId ) AS RowNum
from FuelClaims fc
INNER JOIN Vehicles v on fc.VehicleId =v.VehicleId
INNER JOIN Drivers d on d.DriverId =v.OfficialID
INNER JOIN Departments de on de.DepartmentId =d.DepartmentId
INNER JOIN Provinces p on de.ProvinceId =p.ProvinceId
INNER JOIN FuelRates f on f.FuelRateId =fc.FuelRateId
INNER JOIN FuelClaimStatuses fs on fs.FuelClaimStatusId= fc.statusid
INNER JOIN LogsheetMonths l on l.LogsheetMonthId =f.LogsheetMonthId
Where fc.IsDeleted = 0) AS MyDerivedTable WHERE MyDerivedTable.RowNum BETWEEN
600000 And 600010
您应该发布执行计划,但性能问题的可能原因是索引不足或缺乏索引 确保你有 你所有外键关系的索引 检索和选择字段的覆盖索引 覆盖指数 请尝试以下方法:
SELECT TOP 10 fc.FuelClaimId
FROM FuelClaims fc
INNER JOIN Vehicles v ON fc.VehicleId = v.VehicleId
INNER JOIN Drivers d ON d.DriverId = v.OfficialID
INNER JOIN Departments de ON de.DepartmentId = d.DepartmentId
INNER JOIN Provinces p ON de.ProvinceId = p.ProvinceId
INNER JOIN FuelRates f ON f.FuelRateId = fc.FuelRateId
INNER JOIN FuelClaimStatuses fs ON fs.FuelClaimStatusId = fc.statusid
INNER JOIN LogsheetMonths l ON l.LogsheetMonthId = f.LogsheetMonthId
WHERE fc.IsDeleted = 0 AND fc.FuelClaimId BETWEEN 600001 AND 600010
ORDER BY fc.FuelClaimId
也就是说,介于10和20之间的值包含在内,所以实际上返回10,11,12,13,14,15,16,17,18,19和20,所以11行不是10。由于标识值通常从1开始,因此您确实希望在11和20之间,因此在上面的示例中为600001
上面的查询应该可以解决在查询更大范围的项目时性能下降的问题
虽然它不会总是返回10条记录,但修复方法是:
WHERE fc.IsDeleted = 0 AND fc.FuelClaimId > @LastMaxFuelClaimId
其中@LastMaxFuelClaimId是从上一次查询执行返回的上一个MAX FuelClaimId
编辑:之所以速度越来越慢,是因为它必须读取越来越多的表才能读取下一个数据块,它不会跳过读取前600000条记录,而是读取所有记录,然后只返回下一个10条记录,因此每次查询时,它都会重新读取以前的所有记录,上述问题与此不同。您应该给出您的过程定义。我使用了所有外键作为主键,因此会在主键上自动创建索引…@Smith.Patel-True,但不会在外键上自动创建索引。您还可以发布执行计划吗?@Smith.Patel-您可以添加覆盖索引,再试一次并发布新的执行计划吗?如果FuelClaimId是连续的,这会起作用,但可能不是这样。@Lieven我注意到,在我写了它之后,我已经用一个解决方案更新了我的答案,该解决方案在FuelClaimId不连续时有效。+1肯定是比滥用行数更好的解决方案。