5

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

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

它也很慢。

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

4

6 回答 6

3

在处理实体中的日期范围时,这是很常见的情况。简单快捷的方法是在 SQL 中:

将您的事件加入到一个数字生成的日期表中(请参阅 从日期范围生成天数),以便您在一个人或多个人被占用的每一天都有一行。一旦您以这种形式获得数据,只需按日期的周日期部分分组并计算每个分组的行数。

您可以将此扩展为按人分组以进行多人查询。

于 2012-12-17T12:08:51.657 回答
2

从 SQL 的角度来看,我建议使用存储过程并传入您的日期/范围要求,然后您可以为一个用户或可能的多个用户返回一个记录集。这样,您的代码只需访问 db 一次。

然后,您可以通过迭代一次输出记录集数据。

希望这可以帮助。

于 2012-12-14T23:20:51.367 回答
1

使用存储过程将您的查询触发到 SQL 以获取数据。

在您的情况下将参数传递给 SQl 查询的是今天的日期。

在 SQL 存储过程中应用你的条件和逻辑,使用过程是从 SQL 中检索数据的好和最快的方法,它也可以防止你的代码被 SQL 注入。

从您的代码中调用该 SP,因为我不知道 raisl 上的 Ruby,我无法为您提供有关如何从中调用存储过程的步骤。

之后,根据您的存储过程提取的数据将在数据表或类似的东西中可用。

获取数据后,您可以执行所有您需要的操作

希望这可以帮助

于 2012-12-20T06:39:55.007 回答
1

查看执行了什么查询。您可以进一步向您的查询做出解释

explain select * from  project where start_date < any_date and end_date> any_date2

你看查询的计划。使用此计划来优化您的查询。例如:如果您有使用字段 end_date 的索引,请替换条件(end_date> any_date2 and start_date < any_date) 。如果您在此字段上有索引,此步骤将使用索引。但它的步骤是依赖于数据库的。示例适用于 nysql。如果要在 mysql 中使用索引,则必须在 where 的左侧使用索引条件

于 2012-12-21T09:45:02.173 回答
1

您的问题中没有足够的信息来确切地知道您要在这里实现什么,例如代码片段没有使用返回的数据库查询,因此您可以将其删除以使其更快。也许这只是您发布的代码中的一个错误?

话虽如此,您应该研究一些技术来实现您的功能。

我会看看使用数据仓库技术。我会将您的“可用性信息”视为星型模式中的事实表,将“日期”和“人员”视为维度表。

然后,您可以使用查询来获取诸如本周该项目的用户列表及其可用性之类的内容。

数据仓库有一大堆资源,您可以利用它来帮助使其表现良好,但也有很多术语可能会令人困惑,但对于这种类型的“我需要在几组事物中对数据进行切片和切块” (人和时间)',数据仓库技术可以非常强大。

于 2012-12-23T23:46:21.380 回答
1

由于我不了解 ruby​​ on rails,从 sql 的角度来看,我建议您编写一个存储过程并返回一个数据集。并从前端对数据集进行必要的表操作。这将减少对 DB 的不必要调用。

于 2012-12-24T05:25:03.637 回答