我有一个日历,用于存储基于任何用户的日期(而不是日期时间)的信息。
在我的网站上,用户可以选择特定日期并填写该日期的一些有关自己的信息。 此时,我的表结构如下所示
+----+---------+------------+-----------+
| id | user_id | event_date | data |
+----+---------+------------+-----------+
| 1 | 25 | 2015-08-25 | Some Data |
+----+---------+------------+-----------+
实际上,列数据并不存在,而是有多个 bool 列,但这样更简单。
重要的是我需要获取每个用户一天的所有数据字段。并且需要尽可能快。
目前,我只是运行以下查询。
SELECT `data` FROM `calendar` WHERE `event_date` = '2015-07-08'
我的问题是,采用这种结构,我的表的大小随着时间的推移逐渐增加,并且从此表中进行 SELECT 操作变得越来越慢(目前有约 20 000 000 行)。
我已经删除了一年以上的数据,但由于用户数量在增加,我的表也在增加。
有一点需要注意,在网站上,用户可以使用某种重复事件来填充日历。它看起来像下面这样:
For Every Monday & Saturday From [start_date] to [end_date], set data="Some Value".
因此,我想知道使用表结构来存储重复事件是否比当前表更好。 我见过this answer (和其他类似的)提出以下结构
Assuming I have two tables, one called events like this:
ID NAME 1 Sample Event 2 Another Event
And a table called events_meta like this:
ID event_id meta_key meta_value 1 1 repeat_start 1299132000 2 1 repeat_interval_1 432000
但是这个结构似乎不符合我的需要:
- 它似乎没有处理异常(该事件每周六重复一次,但不是这个)
- 恐怕从
repeat_start
和repeat_interval
获取日期所需的计算时间会比当前选择时间长。
是否有更好的表结构来存储日期数据?正如我所说,我的需要是尽快获取特定日期的每个用户的数据。
PS:我的 event_date
列上已经有一个 INDEX。
这里是查询的解释和SHOW CREATE TABLE的结果
+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+
| 1 | SIMPLE | calendar | ref | event_date | event_date | 3 | const | 127591 | NULL |
+----+-------------+----------+------+---------------+------------+---------+-------+--------+-------+
CREATE TABLE IF NOT EXISTS `calendar` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`event_date` date NOT NULL,
`data` varchar(128) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_index` (`user_id`,`event_date`),
KEY `event_date` (`event_date`)
)
最佳答案
没有任何改善。
您有INDEX(event_date)
。真正的“问题”是 EXPLAIN 中使用的 event_date 大约有 127K 行。从磁盘获取这么多行需要很长时间。
好的,可能有一种方法可以改进此查询 - 但它可能会以牺牲其他查询为代价。为了了解提出什么建议(以及是否提出建议),请提供
显示创建表
- 其他重要的
SELECT
。 - 典型一天有多少行?典型用户有多少行?
您实际上在客户端中使用了所有 127K 行吗?或者你做进一步的过滤?或者合并(求和、计数等)?也许其中一些内容可以移至SELECT
。
关于mysql - 日历的表结构 - 基于日期存储数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31298173/