在我们的应用中,人们有一个或多个项目。这些项目有开始和结束日期。人们的可用天数有限。
现在我们有一个页面,以逐周显示给定人员的可用性。它目前显示18周。
我们目前计算给定周的可用时间的方式如下:
def days_available(query_date=Date.today)
days_engaged = projects.current.where("start_date < ? AND finish_date > ?", query_date, query_date).sum(:days_on_project)
available = days_total - hours_engaged
end
这意味着要显示应用程序上方描述的页面,将向数据库发出18(!)个查询。我们有一些页面列出了表格中多人的可用性。对于这些页面,查询量很快就会变得惊人。
这也很慢。
我们如何以更高效的方式处理可用性检索?
答案 0 :(得分:3)
在实体中处理日期范围时,这是一种非常常见的情况。简单快捷的方法是在SQL中:
将您的活动加入到生成的数字日期表(请参阅generate days from date range),以便每个人或每个人都被占用一天。获得此表单中的数据之后,只需按日期的星期日部分进行分组,并计算每个分组的行数。
您可以将此扩展为逐个人进行多人查询。
答案 1 :(得分:2)
从SQL的角度来看,我建议使用存储过程并传入日期/范围要求,然后可以为用户或可能多个用户返回记录集。这样你的代码就必须访问db一次。
然后,您可以通过迭代一次输出记录集数据。
希望这有帮助。
答案 2 :(得分:1)
USE用于将查询激发到SQL以获取数据的存储过程。
在您的情况下传递参数,它是SQl查询的今天日期。
在SQL存储过程中应用您的条件和逻辑,使用过程是从SQL检索数据的最佳方式,也是防止SQL注入代码的最快方法。
从您的代码中调用该SP,因为我不知道Ruby on raisl我无法为您提供有关如何从中调用存储过程的步骤。
之后根据您的存储过程fdetched的数据将在数据表或类似的表格中提供。
获取数据后,您可以执行所需的一切
希望这有帮助
答案 3 :(得分:1)
查看执行的查询。您可以进一步向您的查询提出解释
explain select * from project where start_date < any_date and end_date> any_date2
您会看到查询计划。使用此计划优化您的查询。 例如 : 如果你有索引使用字段end_date替换条件(end_date&gt; any_date2和start_date&lt; any_date)。如果您在此字段上有索引,则此步骤将使用索引。但它的步骤依赖于数据库。例子是nysql。如果你想在mysql中使用索引,你必须在where
的左侧部分使用索引条件答案 4 :(得分:1)
您的问题中没有足够的信息可以准确了解您在此处尝试实现的目标,例如:代码段不使用返回的数据库查询,因此您可以删除它以使其更快。也许这只是您发布的代码中的一个错误?
话虽如此,您应该考虑一些技术来实现您的功能。
我会看一下使用数据仓库技术。我会将您的“可用性信息”视为星型架构中的Fact表,其中'Dates'和'People'作为Dimension表。
然后,您可以使用查询来获取本周此项目的用户列表及其可用性。
数据仓库拥有大量资源,您可以利用这些资源来帮助提高性能,但是还有很多术语可能令人困惑,但是对于这种类型的'我需要将数据切片并切成几个一组事物(人和时间)',数据仓库技术可以非常强大。
答案 5 :(得分:1)
由于我不理解rails上的ruby,从sql的角度来看,我建议你编写一个存储过程并返回一个数据集。并从前端对数据集进行必要的表操作。它将减少对DB的不必要的调用