【发布时间】:2015-09-11 20:05:45
【问题描述】:
我希望提高对我拥有的非常大的 MySQL 分析表的查询速度。该表正在跟踪游戏服务器上的玩家数量,其结构如下所示:
`server_tracker` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ip` int(10) unsigned NOT NULL,
`port` smallint(5) unsigned NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`players` tinyint(3) unsigned NOT NULL,
`map` varchar(28) NOT NULL,
`portjoin` smallint(5) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_tracking_ip_port` (`ip`,`port`)
) ENGINE=InnoDB AUTO_INCREMENT=310729056 DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED |
此表的插入频率很高,每小时跟踪 10k+ 台服务器 10+ 次。然而,每隔一小时,数据就会被取出并取平均值,然后放入一个结构基本相同的“平均”表中。
目前我将 IP/端口设置作为关键。但是 - 有时在进行每小时平均时可能会有点慢 - 所以我很好奇是否值得在时间戳上放置一个索引,它经常用于从特定时间范围内选择数据,如下所示:
SELECT `players`
FROM `server_tracker`
WHERE `ip` = x
AND `port` = x
AND `date` > NOW()
AND `date` < NOW() + INTERVAL 60 MINUTE
ORDER BY `id` DESC
这是在此表上运行的唯一查询类型。该表仅用于在特定时间范围内从游戏服务器获取玩家人数。数据永远不会更新或更改。
但是,我对这一切有点陌生——我不确定在时间戳上放置索引是否能起到很多作用。只是在寻找一些友好的建议。
EXPLAIN SELECT players FROM server_tracker WHERE ip = x AND port = x AND date > NOW() AND date < NOW() + INTERVAL 60 MINUTE ORDER BY id DESC的结果
+----+-------------+-----------------+------+----------------------+----------------------+---------+-------------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------------+------+----------------------+----------------------+---------+-------------+-------+-------------+
| 1 | SIMPLE | server_tracker | ref | idx_tracking_ip_port | idx_tracking_ip_port | 6 | const,const | 15354 | Using where |
+----+-------------+-----------------+------+----------------------+----------------------+---------+-------------+-------+-------------+
【问题讨论】:
-
是的,您可能需要在
WHERE子句中使用的任何内容的索引。 -
重要的是要了解所有查询的访问路径,这些查询是尝试制作索引(单列、复合、覆盖)的瓶颈。否则,我们只能给出广泛的笔触答复。如果采取错误的方式,会让你的情况更糟
-
@ceejayoz 我的问题是这会显着增加磁盘空间使用量吗?它是否必须将这些数百万行超时增长的所有这些日期保存到一个文件中?我不确定索引在内部是如何工作的,因为大多数解释只解释了为什么以及如何使用它们。
-
@Drew “访问路径”是什么意思?例如,我将在此表上运行的查询类型?我正在运行的唯一查询类型是 OP 中的选择查询。通过查找 IP/端口/日期来选择玩家数量。这些数据永远不会更新或更改 - 但它确实会经常被删除。
-
正确。你的情况很好,因为没有什么其他查询......索引更改会影响。