我有这个表,它包含大约80,000,000行。
CREATE TABLE `mytable` (
`date` date NOT NULL,
`parameters` mediumint(8) unsigned NOT NULL,
`num` tinyint(3) unsigned NOT NULL,
`val1` int(11) NOT NULL,
`val2` int(10) NOT NULL,
`active` tinyint(3) unsigned NOT NULL,
`ref` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ref`) USING BTREE,
KEY `parameters` (`parameters`)
) ENGINE=MyISAM AUTO_INCREMENT=79092001 DEFAULT CHARSET=latin1
它围绕着两个主要栏目:“参数”和“日期”。 “参数”有大约67,000个可能的值 对于每个“参数”,大约有1200行,每行具有不同的日期。 所以对于每个日期,有67,000行。 1200 * 67,000 = 80,400,000。
表大小显示为1.5GB,索引大小为1.4GB。
现在,我想查询表以检索一个“参数”的所有行 (实际上我想为每个参数做这个,但这是一个好的开始)
SELECT val1 FROM mytable WHERE parameters=1;
第一次运行会在8秒内给出结果 对于不同但接近的参数值(2,3,4 ......)的后续运行是瞬时的
“远离”值的运行(参数= 1000)再次给我8秒的结果。
我在没有索引的情况下运行相同查询的测试,并在20秒内得到结果,所以我猜索引如EXPLAIN所示,但没有给表现大幅提升:
+----+-------------+----------+------+---------------+------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------------+---------+-------+------+-------+
| 1 | SIMPLE | mytable | ref | parameters | parameters | 3 | const | 1097 | |
+----+-------------+----------+------+---------------+------------+---------+-------+------+-------+
但我仍然感到困惑的是这个简单的请求(没有加入,直接在索引上)。
该服务器是2年前运行Ubuntu的2 cpu四核2.6GHz,带有4G的RAM。 我已经将key_buffer参数提升到了1G,并重新启动了mysql,但没有发现任何变化。 我应该认为这是正常的吗?还是有什么我做错了?我得到了正确配置的感觉,请求几乎是即时的。答案 0 :(得分:0)
尝试使用覆盖索引,即创建包含所需两个列的索引。它不需要第二个磁盘I / O来从主表中获取值,因为数据正好在索引中。