我怎么能以更高效的方式编写这段代码?

时间:2012-12-14 21:22:12

标签: sql ruby-on-rails-3 performance

在我们的应用中,人们有一个或多个项目。这些项目有开始和结束日期。人们的可用天数有限。

现在我们有一个页面,以逐周显示给定人员的可用性。它目前显示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(!)个查询。我们有一些页面列出了表格中多人的可用性。对于这些页面,查询量很快就会变得惊人。

这也很慢。

我们如何以更高效的方式处理可用性检索?

6 个答案:

答案 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的不必要的调用