我有一个非常简单的MYSQL数据库,只有3列但数百万行。 其中两个列(hid1,hid2)描述了研究对象(约50,000个),第三列(得分)是hid1与hid2比较的结果。因此,行数是max(hid1)* max(hid2),这是一个非常大的数字。因为该表只需要写一次并且读数百万次,所以我选择了一个MyISAM表(我希望这是一个好主意)。最初,我计划为一对给定的hid1,hid2检索“得分”,但结果更方便的是检索给定hid1的所有得分(和hid2)。
我的表格(“结果”)如下所示:
+-------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+-------+
| hid1 | mediumint(8) unsigned | YES | MUL | NULL | |
| hid2 | mediumint(8) unsigned | YES | | NULL | |
| score | float | YES | | NULL | |
+-------+-----------------------+------+-----+---------+-------+
,典型的查询将是
select hid1,hid2,score from result where hid1=13531 into outfile "/tmp/ttt"
问题在于:查询花费的时间太长,至少有时候。对于某些'hid1'值,我会在一秒钟内得到结果。对于其他hid1(特别是对于大数字),我必须等待最多40秒。正如我所说,我必须运行数千个这样的查询,所以我对加快速度感兴趣。
让我重申一下:查询大约有50,000次点击,我不需要任何特定的顺序。我在这里做错了什么,或者像MySQL这样的关系数据库不能完成这项任务?
我已经尝试过在/etc/mysql/my.conf中增加key_buffer 这似乎有所帮助,但并不多。 hid1上的索引是几GB,key_buffer必须大于索引大小才有效吗?
任何暗示都会受到赞赏。
编辑:这是一个使用相应的'explain'输出运行的示例:
select hid1,hid2,score from result where hid1=132885 into outfile "/tmp/ttt"
Query OK, 16465 rows affected (31.88 sec)
如下所示,实际上正在使用索引hid1_idx:
mysql> explain select hid1,hid2,score from result where hid1=132885 into outfile "/tmp/ttt";
+----+-------------+--------+------+---------------+------------+---------+-------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------------+---------+-------+-------+-------------+
| 1 | SIMPLE | result | ref | hid1_index | hid1_index | 4 | const | 15456 | Using where |
+----+-------------+--------+------+---------------+------------+---------+-------+-------+-------------+
1行(0.00秒)
我觉得令人费解的是,hid1的低数字查询总是比高数字的查询要快得多。这不是我对使用索引的期望。
答案 0 :(得分:2)
两个随机建议,基于始终涉及hid1
上的相等过滤器的查询模式:
使用InnoDB表并利用(hid1, hid2)
上的聚簇索引。这样,属于同一个隐藏的所有行都将物理地放在一起,而将加速撤退。
使用合适的nr分区对hid1上的表进行哈希分区。
答案 1 :(得分:1)
优化类似查询的最简单方法是使用索引。像
这样简单的事情alter table results add index(hid1)
会改善您发送的查询。更重要的是,如果您想同时按两个字段进行搜索,则可以在索引中使用这两个字段。
alter table results add index(hid1, hid2)
这样,MySQL可以以非常有条理的方式访问结果,并找到您想要的信息。
如果您对第一个查询运行说明,您可能会看到类似
的内容| select_type | table | type|possible_keys| rows |Extra
| SIMPLE | results| ALL | | 7765605| Using where
添加索引后,您应该看到
| select_type | table | type|possible_keys| rows |Extra
| SIMPLE | results| ref |hid1 | 2816304|
在第一种情况下,它告诉您需要检查所有行,在第二种情况下,它可以使用 ref
答案 2 :(得分:0)
如果您知道hid1和hid2的组合是唯一的,您应该考虑将其作为主键。这也会自动为hid1添加一个索引。请参阅:http://dev.mysql.com/doc/refman/5.5/en/multiple-column-indexes.html
另外,检查EXPLAIN的输出。请参阅:http://dev.mysql.com/doc/refman/5.5/en/select-optimization.html和相关链接。