如何最好地将now()
的值向下舍入(即“下限”)到最近的小时?
这是为了使query cache能够有效地使用以下语句:
SELECT SQL_CACHE * FROM table WHERE appointment_date >= NOW()
答案 0 :(得分:1)
除非您在应用程序层中进行舍入,否则不要指望MySQL足够聪明以使用查询缓存。 Any query that includes NOW() (and many other functions) will never be cached.
也就是说,如果你计算了应用程序层中最近的小时,它应该可以正常工作。
答案 1 :(得分:1)
如果您有无法缓存的查询,可以将其拆分为两个更简单的查询。第一个查询将根据不可缓存的函数返回行ID;第二个查询将完成剩下的工作。所以至少第二个查询将被缓存。
使用您的示例,您可以进行两次查询:
...因此您的应用程序将收集ID。如果返回任何ID,请将它们组合为逗号分隔的字符串并运行第二个查询:
当然,您的查询非常简单,但如果您有非常复杂的大型查询,则可以通过编程方式对其进行拆分。例如,您可以使用正则表达式和函数来查明查询是否是不可缓存的,并且值得拆分它。例如,您可以使用以下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())并仅使用客户端比较。我们在服务器中使用这种方法。如果查询只返回一些数据,则无法拆分它。但如果它返回大量数据,就像我在下面解释的那样。所以你的查询就是这样:
或者您可以设置日期粒度(例如,一个月,一天或一小时)并将其添加到比较中。此粒状日期应由您的软件预先计算,例如:
(此'2017-05-10'值应由您的软件计算,每天只更改一次。)
然后您收到了appointment_date并将其与客户端的当前时间进行比较。如果时间匹配,则运行第二个查询,如上面的示例#2所示。
当然,这些示例非常简单,我们在服务器中使用了更复杂的查询。