Mysql WHERE子句中日期和日期时间之间的差异

Mysql WHERE子句中日期和日期时间之间的差异,mysql,sql,Mysql,Sql,比如说,我有一张桌子: +------------+-----------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +------------+-----------+------+-----+-------------------

比如说,我有一张桌子:

+------------+-----------+------+-----+-------------------+-----------------------------+
| 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\u操作
,以及在网站上执行时的
a\u日期
a\u日期时间

我的问题是,当我想返回按日期分组的每个
id\u动作的
COUNT()
时,这两个选项是相同的,还是速度不同?谢谢你的解释

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


换句话说,我的问题是,每个动作都有它的
datetime
,如果我真的需要列
a_date
,或者使用
date\u FORMAT
函数和列
a_datetime
是一样的,我不需要列
a_date

如果您在group by子句中执行函数:“group by date\u FORMAT”(a_datetime,'%Y-%m-%d')”,您将无法利用索引:“a_datetime”

至于速度,我相信datetime索引和date索引之间不会有明显的区别(但用“解释”测试总是很容易的)


最后,您始终可以将日期时间读取为日期(如果需要,可以使用cast函数)如果你有一个AyDATA和AYDATE时间,你的模式就不规范了。你应该考虑删除其中一个。如果日期为你的应用程序提供了足够的粒度,那么就去掉DATETIME。否则,如果你在GROUPBY子句中做了一个函数:“按DATEY格式分组”,则去掉AyDATE并按要求铸造< < /P> > P>。(a_datetime,'%Y-%m-%d')”,您将无法利用索引:“a_datetime”

至于速度,我相信datetime索引和date索引之间不会有明显的区别(但用“解释”测试总是很容易的)


最后,您始终可以将日期时间读取为日期(如果需要,可以使用cast函数)如果你有一个AyDATA和AYDATE时间,你的模式就不规范了。如果日期为你的应用程序提供了足够的粒度,那么就去掉DATETIME。否则,去掉AyDATE并按需要投下< /P> <强>日期:< /强>:日期类型用于具有日期部分但没有时间部分的值。

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

所以,若你们有DATETIME,你们总是可以从中得到DATE,但从DATE你们不能得到DATETIME

根据您的sql,不会有重大区别

最好不要有
a_日期
,因为你已经有了
a_日期时间。


但一般来说,如果您可以使用
时间戳
,您应该这样做,因为它比
日期时间
日期更节省空间:日期类型用于有日期部分但没有时间部分的值

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

所以,若你们有DATETIME,你们总是可以从中得到DATE,但从DATE你们不能得到DATETIME

根据您的sql,不会有重大区别

最好不要有
a_日期
,因为你已经有了
a_日期时间。


但一般来说,如果您可以使用
时间戳
,您应该这样做,因为它比
日期时间
更节省空间

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

该表有10634079行

第一次尝试最初需要10.66秒,以后每次尝试都需要10秒左右

秒查询第一次执行需要1.25分钟,第二次、第三次执行需要22.091秒

因此,在我看来,如果您想要性能,那么必须有一个列a_date,因为在没有date_格式的情况下执行时,需要花费一半的时间


如果性能不是最主要的考虑因素(比如数据冗余),那么datetime列将用于所有其他与日期/日期时间相关的目的。

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

该表有10634079行

第一次尝试最初需要10.66秒,以后每次尝试都需要10秒左右

秒查询第一次执行需要1.25分钟,第二次、第三次执行需要22.091秒

因此,在我看来,如果您想要性能,那么必须有一个列a_date,因为在没有date_格式的情况下执行时,需要花费一半的时间


如果性能不是最主要的考虑因素(比如数据冗余),那么“日期时间”列将用于所有其他与日期/日期时间相关的目的。

由于您的转换,使用“日期”按天分组将比“日期时间”更有效。在T-SQL中,我使用DATEADD()和DATEDIFF()的组合仅从DATETIME获取日期,因为数学比数据转换更有效。例如(同样,使用T-SQL,尽管我确信MySQL也有类似的功能):

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

也许MySQL版本会是:

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

很抱歉,我没有安装MySQL,或者我自己也会尝试。我希望它比强制转换/格式化更有效,但比使用日期效率更低。

由于您的转换,使用日期分组将比使用日期时间更有效率。在t-SQL中,我使用DATEADD()和DATEDIFF()的组合仅从DATETIME获取日期,因为数学比数据转换更有效。例如(同样,使用T-SQL,尽管我确信MySQL也有类似的功能):

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

也许MySQL版本会是:

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

很抱歉,我没有安装MySQL,或者我会自己尝试。我希望它比强制转换/格式化更有效,但比使用日期效率更低。

如前所述,pe
DATE_ADD('2014-01-01', INTERVAL DATEDIFF('2014-01-01',a_datetime) DAY)