1

我如何最好地将(即“地板”)的值向下舍now()入到最接近的小时?

这是为了使查询缓存有效地与以下语句一起工作:

SELECT SQL_CACHE * FROM table WHERE appointment_date >= NOW()
4

2 回答 2

2

除非您在应用程序层进行四舍五入,否则不要期望 MySQL 足够聪明以使用查询缓存。任何包含 NOW() (以及许多其他函数)的查询都不会被缓存。

也就是说,如果您确实在应用程序层计算最近的时间,它应该可以正常工作。

于 2013-11-13T19:28:55.100 回答
1

如果您有无法缓存的查询,您可以将其拆分为两个更简单的查询。第一个查询将根据不可缓存的函数返回行 ID;第二个查询将完成其余的工作。所以至少第二个查询将被缓存。

使用您的示例,您可以进行两个查询:

  1. 从表中选择 ID WHERE 约会日期 >= NOW();

...因此您的应用程序将收集 ID。如果返回任何 ID,请将它们组合成一个逗号分隔的字符串并运行第二个查询:

  1. SELECT * FROM table WHERE ID IN (".$ids.");"

当然,您的查询非常简单,但是如果您有非常复杂且大型的查询,您可以通过编程方式将它们拆分。例如,您可以使用正则表达式和函数来确定查询是否不可缓存,是否值得拆分。例如,您可以为此目的使用以下 PHP 函数:

function query_cannot_be_cached($query)
{
  return preg_match("/\b(?:AES_DECRYPT|AES_ENCRYPT|BENCHMARK|CONNECTION_ID|CONVERT_TZ|CURDATE|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURTIME|DATABASE|ENCRYPT|FOUND_ROWS|GET_LOCK|IS_FREE_LOCK|IS_USED_LOCK|LAST_INSERT_ID|LOAD_FILE|MASTER_POS_WAIT|NOW|PASSWORD|RAND|RANDOM_BYTES|RELEASE_ALL_LOCKS|RELEASE_LOCK|SLEEP|SYSDATE|UNIX_TIMESTAMP|USER|UUID|UUID_SHORT)\b *\(/i", $query);
}

另一种解决方案是避免服务器端比较 (Now()) 并仅使用客户端比较。我们在我们的服务器中使用这种方法。如果查询只返回少量数据,则不能拆分它。但是,如果它返回大量数据,请按照我在下面的解释进行拆分。所以你的查询将是这样的:

  • 从表中选择约会日期,id;

或者您可以设置日期粒度(例如,一个月、一天或一小时)并将其添加到比较中。这个粒度日期应该由您的软件提前计算,例如:

  • 选择约会日期,id FROM 表 WHERE 约会日期 > '2017-05-10';

(这个 '2017-05-10' 值应该由您的软件计算,它每天只更改一次)。

然后您收到约会日期并将其与客户端的当前时间进行比较。如果时间匹配,则运行第二个查询,如上面的示例 #2 所示。

当然,这些示例非常简单,我们在服务器中使用了更复杂的查询。

于 2017-05-02T01:38:40.223 回答