我有一个这样的存储过程:
声明@where nvarchar(max)
set @where=' where 1=1 '
if(@IsSimNha is not null)
set @where+=' and s.IsSimNha=@IsSimNha'
if(@IsSearchSimPSC is not null)
set @where+=' and s.HanPhaiPhatSinhLai<=@HanPhaiPhatSinhLai'
if(@GiaTu is not null)
set @where+=' and s.AgentPrice>=@GiaTu'
if(@GiaDen is not null)
set @where+=' and s.AgentPrice<=@GiaDen'
if(@AgentID is not null)
set @where+=' and s.AgentId=@AgentID'
if(@NhaMangId is not null)
set @where+=' and s.NhaMangId=@NhaMangId'
if(@TinhTrangID is not null)
set @where+=' and s.StatusId=@TinhTrangID'
if(@NgayNhapTu is not null)
set @where+=' and s.NgayNhapSim>=@NgayNhapTu'
if(@NgayNhapDen is not null)
set @where+=' and s.NgayNhapSim<=@NgayNhapDen'
if(@NgayPscTu is not null)
set @where+=' and s.NgayPhatSinhCuoc>=@NgayPscTu'
if(@NgayPscDen is not null)
set @where+=' and s.NgayPhatSinhCuoc<=@NgayPscDen'
if(@HanPSCTu is not null)
set @where+=' and s.HanPhaiPhatSinhLai>=@HanPSCTu'
if(@HanPSCDen is not null)
set @where+=' and s.HanPhaiPhatSinhLai<=@HanPSCDen'
if(@HanSuDungTu is not null)
set @where+=' and s.HanSuDung>=@HanSuDungTu'
if(@HanSuDungDen is not null)
set @where+=' and s.HanSuDung<=@HanSuDungDen'
if(@SoSeri is not null)
set @where+=' and s.SoSeri<=@SoSeri'
if(@Lenght is not null)
set @where+=' and LEN(s.Number) = @Lenght'
if(@SearchDau is not null)
set @where+=' and s.Number like @SearchDau+''%'''
if(@SearchGiua is not null)
set @where+=' and s.Number like ''%''+@SearchGiua+''%'''
if(@SearchCuoi is not null)
set @where+=' and s.Number like ''%''+@SearchCuoi'
set @sql = 'declare @TotalItemCount int;'
set @sql+= ' select @TotalItemCount=count(1)
from sims s with (NOLOCK) '
+@where
set @sql+=' select @TotalItemCount TotalItemCount, s.SimId,s.Number, s.DisplayNumber, s.AgentId,ag.Email,ag.Mobile2,s.NhaMangId,s.StatusId,s.SalelPrice,
s.SaleOffPrice,s.Commisions,s.AgentPrice,s.HoaHong,s.IsShow,s.DateCreated,ag.AgentName,s.SoSeri,s.SimTypeId,
s.NgayPhatSinhCuoc,s.HanPhaiPhatSinhLai,s.MaCaNhan,s.SoPhatSinhCuoc,s.HanSuDung,s.GhiChu,s.SoTienCamKet,s.SoThangCamKet,
s.NgayKichHoat, s.NgayNhapSim,s.IsSimNha,s.CoHoTroTraGop,s.GhiChuTraGop,s.ViTriId
from sims s with (NOLOCK) left join Agents ag with (NOLOCK) on s.AgentID=ag.AgentID ' +@where
declare @orderbysql nvarchar(max);
if(@OrderBy='SalelPrice')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.SalelPrice asc '
else set @orderbysql= N' ORDER BY s.SalelPrice desc '
end
else if(@OrderBy='SaleOffPrice')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.SaleOffPrice asc '
else set @orderbysql= N' ORDER BY s.SaleOffPrice desc '
end
else if(@OrderBy='AgentPrice')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.AgentPrice asc '
else set @orderbysql= N' ORDER BY s.AgentPrice desc '
end
else if(@OrderBy='NgayPSC')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.NgayPSC asc '
else set @orderbysql= N' ORDER BY s.NgayPSC desc '
end
else if(@OrderBy='HanPhatSinhCuoc')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.HanPhatSinhCuoc asc '
else set @orderbysql= N' ORDER BY s.HanPhatSinhCuoc desc '
end
else if(@OrderBy='HanSuDung')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.HanSuDung asc '
else set @orderbysql= N' ORDER BY s.HanSuDung desc '
end
else if(@OrderBy='NgayNhapSim')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.NgayNhapSim asc '
else set @orderbysql= N' ORDER BY s.NgayNhapSim desc '
end
else if(@OrderBy='Number')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.Number asc '
else set @orderbysql= N' ORDER BY s.Number desc '
end
else if(@OrderBy='TenDaiLy')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.TenDaiLy asc '
else set @orderbysql= N' ORDER BY s.TenDaiLy desc '
end
else if(@OrderBy='SoSeri')
begin
if(@SortBy=1)
set @orderbysql= N' ORDER BY s.SoSeri asc '
else set @orderbysql= N' ORDER BY s.SoSeri desc '
end
else
begin
if(@SortBy=1)
begin
if(@IsSimNha=1)
set @orderbysql= N' ORDER BY s.HanPhatSinhCuoc asc '
else set @orderbysql= N' ORDER BY s.SimId asc '
end
else
begin
if(@IsSimNha=1)
set @orderbysql= N' ORDER BY s.HanPhatSinhCuoc desc '
else set @orderbysql= N' ORDER BY s.SimId desc '
end
end
set @orderbysql+=' OFFSET (@PageNum-1)* @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY'
set @sql+=@orderbysql
print @sql
EXEC sp_executesql @sql,N'@IsSimNha bit,@IsSearchSimPSC bit, @HanPhaiPhatSinhLai datetime,@GiaTu decimal(18,0),@GiaDen decimal(18,0),@NhaMangId int,@AgentID int,
@TinhTrangID int,@NgayNhapTu datetime,@NgayNhapDen datetime,@NgayPscTu datetime,@NgayPscDen datetime,@HanPSCTu datetime,@HanPSCDen datetime,@HanSuDungTu datetime,
@HanSuDungDen datetime,@SoSeri nvarchar(30),@Lenght int,@SearchDau nvarchar(30),@SearchGiua nvarchar(30),@SearchCuoi nvarchar(30),@PageNum int,@PageSize int ',@IsSimNha ,@IsSearchSimPSC , @HanPhaiPhatSinhLai ,@GiaTu ,@GiaDen,@NhaMangId ,@AgentID ,
@TinhTrangID ,@NgayNhapTu ,@NgayNhapDen ,@NgayPscTu ,@NgayPscDen ,@HanPSCTu ,@HanPSCDen ,@HanSuDungTu ,
@HanSuDungDen ,@SoSeri ,@Lenght ,@SearchDau ,@SearchGiua ,@SearchCuoi,@PageNum,@PageSize
完成时间超过3秒。
但是当我把脚本结果运行时:
select
@TotalItemCount TotalItemCount, s.SimId,s.Number, s.DisplayNumber,
s.AgentId, ag.Email, ag.Mobile2, s.NhaMangId, s.StatusId, s.SalelPrice,
s.SaleOffPrice, s.Commisions, s.AgentPrice, s.HoaHong, s.IsShow,
s.DateCreated, ag.AgentName, s.SoSeri, s.SimTypeId,
s.NgayPhatSinhCuoc, s.HanPhaiPhatSinhLai, s.MaCaNhan, s.SoPhatSinhCuoc,
s.HanSuDung, s.GhiChu, s.SoTienCamKet, s.SoThangCamKet,
s.NgayKichHoat, s.NgayNhapSim, s.IsSimNha, s.CoHoTroTraGop,
s.GhiChuTraGop, s.ViTriId
from
sims s with (NOLOCK)
left join
Agents ag with (NOLOCK) on s.AgentID = ag.AgentID
where
s.Number like '0973688639'+'%'
order by
s.SimId desc
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
并且运行,它只需要0.02s
我不知道为什么这么慢。
注意:@sql variable =第二个脚本。
有人可以帮助我吗?
全部谢谢
答案 0 :(得分:0)
三件事:
option (recompile)
sims
中所有行的计数
offset / fetch
: A better way - Aaron Bertrand 1)offset ... fetch
这一行之后:
option (recompile)
添加以下行:
set @sql+=@orderbysql ..
2)使用DMV获取表格的行数。
换掉这个:
set @sql+= ' option (recompile);';
为此:
...
set @sql = 'declare @TotalItemCount int;'
set @sql+= ' select @TotalItemCount=count(1)
from sims s with (NOLOCK) '
+@where
set @sql+=' select @TotalItemCount TotalItemCount, s.SimId,s.Number, s.DisplayNumber, s.AgentId,ag.Email,ag.Mobile2,s.NhaMangId,s.StatusId,s.SalelPrice,
s.SaleOffPrice,s.Commisions,s.AgentPrice,s.HoaHong,s.IsShow,s.DateCreated,ag.AgentName,s.SoSeri,s.SimTypeId,
s.NgayPhatSinhCuoc,s.HanPhaiPhatSinhLai,s.MaCaNhan,s.SoPhatSinhCuoc,s.HanSuDung,s.GhiChu,s.SoTienCamKet,s.SoThangCamKet,
s.NgayKichHoat, s.NgayNhapSim,s.IsSimNha,s.CoHoTroTraGop,s.GhiChuTraGop,s.ViTriId
from sims s with (NOLOCK) left join Agents ag with (NOLOCK) on s.AgentID=ag.AgentID ' +@where
...
EXEC sp_executesql @sql,N'@IsSimNha bit,@IsSearchSimPSC bit, @HanPhaiPhatSinhLai datetime,@GiaTu decimal(18,0),@GiaDen decimal(18,0),@NhaMangId int,@AgentID int,
@TinhTrangID int,@NgayNhapTu datetime,@NgayNhapDen datetime,@NgayPscTu datetime,@NgayPscDen datetime,@HanPSCTu datetime,@HanPSCDen datetime,@HanSuDungTu datetime,
@HanSuDungDen datetime,@SoSeri nvarchar(30),@Lenght int,@SearchDau nvarchar(30),@SearchGiua nvarchar(30),@SearchCuoi nvarchar(30),@PageNum int,@PageSize int ',@IsSimNha ,@IsSearchSimPSC , @HanPhaiPhatSinhLai ,@GiaTu ,@GiaDen,@NhaMangId ,@AgentID ,
@TinhTrangID ,@NgayNhapTu ,@NgayNhapDen ,@NgayPscTu ,@NgayPscDen ,@HanPSCTu ,@HanPSCDen ,@HanSuDungTu ,
@HanSuDungDen ,@SoSeri ,@Lenght ,@SearchDau ,@SearchGiua ,@SearchCuoi,@PageNum,@PageSize
3)使用此处描述的...
declare @TotalItemCount int;
select @TotalItemCount=p.rows
from sys.indexes i
inner join sys.partitions p
on p.object_id = i.object_id
and p.index_id = i.index_id
where i.object_id = object_id(N'dbo.sims')
and i.index_id < 2;
set @sql=' select @TotalItemCount as TotalItemCount, s.SimId,s.Number, s.DisplayNumber, s.AgentId,ag.Email,ag.Mobile2,s.NhaMangId,s.StatusId,s.SalelPrice,
s.SaleOffPrice,s.Commisions,s.AgentPrice,s.HoaHong,s.IsShow,s.DateCreated,ag.AgentName,s.SoSeri,s.SimTypeId,
s.NgayPhatSinhCuoc,s.HanPhaiPhatSinhLai,s.MaCaNhan,s.SoPhatSinhCuoc,s.HanSuDung,s.GhiChu,s.SoTienCamKet,s.SoThangCamKet,
s.NgayKichHoat, s.NgayNhapSim,s.IsSimNha,s.CoHoTroTraGop,s.GhiChuTraGop,s.ViTriId
from sims s with (NOLOCK) left join Agents ag with (NOLOCK) on s.AgentID=ag.AgentID ' +@where
...
EXEC sp_executesql @sql
,N'@IsSimNha bit,@IsSearchSimPSC bit, @HanPhaiPhatSinhLai datetime,@GiaTu decimal(18,0),@GiaDen decimal(18,0),@NhaMangId int,@AgentID int,
@TinhTrangID int,@NgayNhapTu datetime,@NgayNhapDen datetime,@NgayPscTu datetime,@NgayPscDen datetime,@HanPSCTu datetime,@HanPSCDen datetime,@HanSuDungTu datetime,
@HanSuDungDen datetime,@SoSeri nvarchar(30),@Lenght int,@SearchDau nvarchar(30),@SearchGiua nvarchar(30),@SearchCuoi nvarchar(30),@PageNum int,@PageSize int, @TotalItemCount bigint'
,@IsSimNha ,@IsSearchSimPSC , @HanPhaiPhatSinhLai ,@GiaTu ,@GiaDen,@NhaMangId ,@AgentID ,
@TinhTrangID ,@NgayNhapTu ,@NgayNhapDen ,@NgayPscTu ,@NgayPscDen ,@HanPSCTu ,@HanPSCDen ,@HanSuDungTu ,
@HanSuDungDen ,@SoSeri ,@Lenght ,@SearchDau ,@SearchGiua ,@SearchCuoi,@PageNum,@PageSize,@TotalItemCount
的替代模式:Pagination with offset / fetch
: A better way - Aaron Bertrand
目标是重新组织动态sql以此模式而不是当前模式生成查询:
这将需要对当前代码进行最多重构,因此如果前两个更改没有帮助,则值得测试:。
offset ... fetch
答案 1 :(得分:0)
我建议你仔细研究一下你的数据类型,特别是nvarchar,我回想一下使用索引扫描而不是索引搜索的执行计划的多个问题只是因为数据类型与你的索引不匹配。
EG(ASP.NET C#):
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT [COLUMN2] FROM [TABLE] WHERE COLUMN1 = @value";
command.Parameters.AddWithValue("@value", orderNumber);
exec sp_executesql N'SELECT [COLUMN2] FROM [TABLE] WHERE COLUMN1 = @Value',N'@Value nvarchar(32)',@Value=N'b12af2381c8a40e7aaf6f682e209b2ed'
这是错误的,因为我们的表使用varchar [32]作为COLUMN1,这默认生成一个NVARCHAR [32]类型的查询。正确的方法是指定类型:
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT [COLUMN2] FROM [TABLE] WHERE COLUMN1 = @value";
command.Parameters.Add("@value", SqlDbType.VarChar, 32);
command.Parameters["@value"].Value = orderNumber; enter code here
exec sp_executesql N'SELECT [COLUMN2] FROM [TABLE] WHERE COLUMN1 = @Value',N'@Value varchar(32)',@Value=N'b12af2381c8a40e7aaf6f682e209b2ed'
不管你信不信,这取决于你的桌子大小和索引,在性能方面会有很大差异。
希望它有所帮助,