如果给定小时属于旺季,找到最佳方法是什么?

时间:2016-07-26 05:19:15

标签: ruby-on-rails ruby database ruby-on-rails-4 rails-activerecord

我正在处理每小时的酒店预订申请。有peak_seasons表存储start_dateend_date。 Peak_Seasons是我的申请中当前年份的预定义日期。每当客户预订所选时间时,我必须检查这些时间是否属于旺季,以便我可以在这些时间内应用不同的费率。

此操作非常频繁,我想优化它。需要想法。我目前的伪代码是:

def calculate_price(customer_start_time, customer_end_time)
    price = 0
    (customer_start_time.to_i...customer_end_time.to_i).step(1.hour) do |hour|
    //now check if this hour belongs to peak season over here
    if peak_seasons?(hour)
      price += price + peak_season_price
    else
      price += price + standard_price
    end
    return price
end

//peak_seasons? somewhere
def peak_seasons?(hour)
    PeakSeason.where("start_date <= ? and end_date >= ?", hour.to_date, hour.to_date).any?
end

我想当客户的hundreads检查所选时间的价格时,这不是有效的代码,然后它将从所选的每小时从DB获取数据。如何优化它?

2 个答案:

答案 0 :(得分:1)

您可以通过缓存所有PeakSeason数据并使用Interval tree(另请参阅this answer)进行计算来创建超高效解决方案。但你说&#34;我想这不是有效的&#34; - 老实说,我建议不要进行这种优化,除非你真的知道 是一个性能问题。

答案 1 :(得分:0)

您可以尝试一次选择给定时间间隔内的所有def all_peak_seasons(customer_start_time, customer_end_time) PeakSeason.where(":start_time BETWEEN start_date AND end_date OR "\ ":end_time BETWEEN start_date AND end_date OR "\ "start_date BETWEEN :start_time AND :end_time", {start_time: customer_start_time, end_time: customer_end_time}) end 条记录。

DECLARE @Tbl TABLE (RowNo INT, Jobname NVARCHAR(50), AuditDate DATETIME)
INSERT INTO @Tbl
SELECT 3, 'Backup Database Sales', '2016.07.26' UNION ALL
SELECT 1, 'Send Autoemail Sales Report', '2016.07.26' UNION ALL
SELECT 2, 'Send Autoemail Sales Report', '2016.07.25' UNION ALL
SELECT 3, 'Send Autoemail Sales Report', '2016.07.24' UNION ALL
SELECT 4, 'Update Sales Stats', '2016.07.23' UNION ALL
SELECT 4, 'Update Sales Stats', '2016.07.22' UNION ALL
SELECT 1, 'Generate new item codes', '2016.07.26' UNION ALL
SELECT 2, 'Generate new item codes', '2016.07.25' 


;WITH CTE
AS
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS Id FROM @Tbl    
)


SELECT
    *
FROM
    @Tbl T
WHERE
    EXISTS
    (
        SELECT TOP 1
            1
        FROM
        (
            SELECT 
                C.Jobname,
                MIN(C.RowNo) MinRowNo,
                MAX(C.RowNo) MaxRow
            FROM 
                CTE C
            GROUP BY
                C.Jobname,
                C.Id - C.RowNo
         ) A
         WHERE
            A.MinRowNo <> A.MaxRow AND
            A.MinRowNo = 1 AND
            A.Jobname = T.Jobname AND
            T.RowNo BETWEEN A.MinRowNo AND A.MaxRow
    )