WHERE子句中DATE和DATETIME之间的区别

时间:2014-12-08 11:47:14

标签: mysql sql mysqli

让我们说,我有一张桌子:

+------------+-----------+------+-----+-------------------+-----------------------------+
| Field      | Type      | Null | Key | Default           | Extra                       |
+------------+-----------+------+-----+-------------------+-----------------------------+
| id         | int(10)   | NO   | PRI |                   | AUTOINCREMENT               |
| id_action  | int(10)   | NO   | IDX |                   |                             |
| a_date     | date      | NO   | IDX |                   |                             |
| a_datetime | datetime  | NO   | IDX |                   |                             |
+------------+-----------+------+-----+-------------------+-----------------------------+

每行都有一些id_action,以及a_datea_datetime在网站上执行时。

我的问题是,当我想返回COUNT()分组id_action的{​​{1}}时,是否相同,当我使用这两个选项时,或者它们的速度不同?谢谢你的任何解释。

a_date

SELECT COUNT(id_action), id_action, a_date
FROM my_table
GROUP BY a_date
ORDER BY a_date DESC

换句话说,我的问题是,每个操作都有SELECT COUNT(id_action), id_action, DATE_FORMAT(a_datetime, '%Y-%m-%d') AS `a_date` FROM my_table GROUP BY DATE_FORMAT(a_datetime, '%Y-%m-%d') ORDER BY a_date DESC ,如果我真的需要列datetime,或者使用a_date函数和列{{ 1}}我不需要列DATE_FORMAT

6 个答案:

答案 0 :(得分:2)

我在MySQL 5.5上的类似表上运行了两个查询。

该表有10634079行。

第一个开始时为10.66,并且在进一步尝试时总是需要大约10秒。

秒查询需要1.25分钟才能执行第一次,第二次,第三次....尝试它花费22.091秒

所以在我看来,如果你正在寻找性能,那么你必须有a_date列,因为它在没有Date_Format的情况下占用了一半的时间。

如果性能不是首要问题(如数据冗余可能),那么a_datetime列将服务于所有其他日期/日期时间相关的目的。

答案 1 :(得分:1)

日期: DATE类型用于具有日期部分但没有时间部分的值。

DATETIME: DATETIME类型用于包含日期和时间部分的值。

所以,如果你有DATETIME,你可以随时从中获取DATE但是从DATE你不能得到DATETIME。

根据你的sql,不会有太大的区别。

最好不要a_date,因为您已经拥有a_datetime.

但一般来说,如果您可以使用TIMESTAMP,那么应该使用DATETIME,因为它比{{1}}更节省空间。

答案 2 :(得分:1)

由于您的转化,使用a_date按天分组将比a_datetime更有效。在T-SQL中,我使用DATEADD()和DATEDIFF()的组合来仅从DATETIME获取日期,因为数学比数据转换更有效。例如(再次使用T-SQL,虽然我确定MySQL有类似的东西):

SELECT COUNT(id_action), id_action,
    DATEADD(DD,DATEDIFF(DD,0,a_datetime),0) AS [a_date]
FROM my_table
GROUP BY DATEADD(DD,DATEDIFF(DD,0,a_datetime),0) AS [a_date]
ORDER BY a_date DESC

这将找到第0天和a_datetime之间的天数,然后再将该天数添加到第0天。 (第0天只是为了简单而选择的任意日期。)

也许MySQL的版本是:

DATE_ADD('2014-01-01', INTERVAL DATEDIFF('2014-01-01',a_datetime) DAY)

抱歉,我没有安装MySQL,或者我自己也会尝试。我希望它比使用a_date更有效,但效率低于使用a_date。

答案 3 :(得分:0)

如果你在group by子句中执行一项功能:“GROUP BY DATE_FORMAT(a_datetime,'%Y-%m-%d')”,你将不会利用你的索引:“a_datetime”。

至于速度,我相信在日期时间与日期的索引之间没有明显的区别(但是使用'explain'测试总是很容易)

最后,您始终可以将日期时间作为日期读取(如果需要,可以使用强制转换函数)。如果同时具有a_date和a_datetime,则不会对架构进行规范化。你应该考虑删除其中一个。如果date为您的应用程序提供了足够的粒度,那么请删除datetime。否则,摆脱a_date并按要求施放

答案 4 :(得分:0)

如前所述,任何函数(o_datetime)的性能都会比a_date更差。选择取决于您的需求,如果不需要DATETIME,请选择DATE,即可。

如果你仍然需要找到要转换的功能,那么我建议你去约会()。

另见How to cast DATETIME as a DATE in mysql?

答案 5 :(得分:0)