在一个非常大的MySQL分析表中 - 我应该为时间戳编制索引吗?

时间:2015-09-11 20:05:46

标签: mysql database indexing

我希望在我拥有的非常大的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 |
+----+-------------+-----------------+------+----------------------+----------------------+---------+-------------+-------+-------------+

1 个答案:

答案 0 :(得分:0)

MySQL和脚本中最重要的信息之一就是知道MySQL的极少数例外,始终只能在查询中使用一个INDEX 。 因此,当在where子句中使用所有4个verfelder时,根据索引设置一个列并不会使用太多。

只有这些字段的组合索引。 字段的顺序对于此索引非常重要,也可用于其他查询。

一个例子:

当您具有WHERE FIELD1或FIELD1和FIELD2或field1,field2和FIELD3时,将使用field1,field2和field3的索引。如果您在WHERE FIELD2中或使用FIELD3或FIELD2和字段,则不使用此索引。 3所以总是使用第一个字段。

很容易发现,如果不像QUERY一样工作,你可以直接运行查询和EXPALIN并直接获取是否使用以及使用哪个索引的信息。如果有几行你可以作为一个指标,行muliplizieren下的各个值一起。此数字越小,您的查询就越好。

MariaDB [tmp]> EXPLAIN select * from content;
+------+-------------+---------+------+---------------+------+---------+------+------+-------+
| id   | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra |
+------+-------------+---------+------+---------------+------+---------+------+------+-------+
|    1 | SIMPLE      | content | ALL  | NULL          | NULL | NULL    | NULL |   13 |       |
+------+-------------+---------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

MariaDB [tmp]>

Anternativ你可以查看探查器查询容量所依赖的QUERY以及优化服务器的时间

一个例子:

MariaDB [(none)]> use tmp
Database changed
MariaDB [tmp]> SET PROFILING=ON;
Query OK, 0 rows affected (0.00 sec)

MariaDB [tmp]>
MariaDB [tmp]> SELECT * FROM content;
+----+------+---------------------+--------+------+--------------+------+------+------+------+
| id | Wert | Zeitstempel         | WertID | aaa  | d            | e    | wwww | n    | ddd  |
+----+------+---------------------+--------+------+--------------+------+------+------+------+
|  1 |   10 | 2001-01-01 00:00:00 |      1 | NULL |       1.5000 | NULL | NULL |    1 | NULL |
|  2 | 12.3 | 2001-01-01 00:01:00 |      2 | NULL |       2.5000 | NULL | NULL |    2 | NULL |
|  3 | 17.4 | 2001-01-01 00:02:00 |      3 | NULL |  123456.1250 | NULL | NULL |    3 | NULL |
|  4 | 10.9 | 2001-01-01 01:01:00 |      1 | NULL | 1000000.0000 | NULL | NULL |    4 | NULL |
|  5 | 15.4 | 2001-01-01 01:02:00 |      2 | NULL |         NULL | NULL | NULL |    5 | NULL |
|  6 | 20.9 | 2001-01-01 01:03:00 |      3 | NULL |         NULL | NULL | NULL |    6 | NULL |
|  7 |   22 | 2001-01-02 00:00:00 |      1 | NULL |         NULL | NULL | NULL |    7 | NULL |
|  8 | 12.3 | 2001-01-02 00:01:00 |      2 | NULL |         NULL | NULL | NULL |    8 | NULL |
|  9 | 17.4 | 2001-01-02 00:02:00 |      3 | NULL |         NULL | NULL | NULL |    
+----+------+---------------------+--------+------+--------------+------+------+------+------+
13 rows in set (0.00 sec)

MariaDB [tmp]>
MariaDB [tmp]> SHOW PROFILE;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000031 |
| checking permissions | 0.000005 |
| Opening tables       | 0.000036 |
| After opening tables | 0.000004 |
| System lock          | 0.000003 |
| Table lock           | 0.000002 |
| After opening tables | 0.000005 |
| init                 | 0.000013 |
| optimizing           | 0.000006 |
| statistics           | 0.000013 |
| preparing            | 0.000010 |
| executing            | 0.000002 |
| Sending data         | 0.000073 |
| end                  | 0.000003 |
| query end            | 0.000003 |
| closing tables       | 0.000006 |
| freeing items        | 0.000003 |
| updating status      | 0.000012 |
| cleaning up          | 0.000003 |
+----------------------+----------+
19 rows in set (0.00 sec)

MariaDB [tmp]>