如何优化SQL Server代码?

时间:2016-05-04 18:10:03

标签: sql sql-server

我有一个包含列的表:Id,time,value。

第一步:给定输入参数作为信号id,开始时间和结束时间,我想首先提取具有信号id的行,并且时间在开始时间和结束时间之间。

第二:假设我在第一步中选择了100行。给定另一个输入参数max_num,我想进一步选择100行中的max_num样本,但是以统一的方式。例如,如果max_num设置为10,那么我将从100行中选择1,11,21,... 91行。

我不确定下面的存储过程是否最佳,如果您发现代码效率低下,请指出并给出一些建议。

create procedure data_selection
@sig_id bigint,
@start_time datetime2, 
@end_time datetime2, 
@max_num float
AS

    BEGIN
    declare @tot float
    declare @step int
    declare @selected table (id int primary key identity not null, Date datetime2, Value real)

    // first step
    insert into @selected (Date, Value) select Date, Value from Table
    where Id = @sig_id
    and Date > = @start_time and Date < = @end_time
    order by Date

    // second step
    select @tot = count(1) from @selected
    set @step = ceiling(@tot / @max_num)
    select * from @selected
    where id % @step = 1

    END

1 个答案:

答案 0 :(得分:2)

已编辑即时计算step。我首先想到这是一个争论。

;with data as (
    select row_number() over (order by [Date]) as rn, *
    from Table
    where Id = @sig_id and Date between @start_time and @end_time
), calc as (
    select cast(ceiling(max(rn) / @max_num) as int) as step from data
)
select * from data cross apply calc as c
where (rn - 1) % step = 0 --and rn <= (@max_num - 1) * step + 1

或者我猜您可以按照您的identity值进行排序/过滤:

;with calc as (select cast(ceiling(max(rn) / @max_num) as int) as step from @selected)
select * from @selected cross apply calc as c
where (id - 1) % step = 0 --and id <= (@max_num - 1) * step + 1

我认为,因为您使用stepceiling四舍五入,所以您可以轻松找到行数少于@max_num的情况。您可能想要向下舍入:case when floor(max(rn) / @max_num) = 0 then 1 else floor(max(rn) / @max_num) end as step