Mysql性能在600万行表上

时间:2009-07-11 20:51:22

标签: mysql performance indexing

有一天,我怀疑我必须学习hadoop并将所有这些数据传输到非结构化数据库,但我很惊讶地发现性能在如此短的时间内显着降低。

我有一个不到600万行的mysql表。 我在这个表上做了一个非常简单的查询,并且相信我已经准备好了所有正确的索引。

查询

SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date

解释返回

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  updateshows     range   date_idx    date_idx    7   NULL    648997  Using where

所以我尽可能使用正确的索引,但这个查询需要11秒才能运行。

数据库是MyISAM,phpMyAdmin表示该表是1.0GiB。

这里有什么想法吗?

编辑: date_idx是date和venid列的索引。那些应该是两个单独的索引吗?

4 个答案:

答案 0 :(得分:42)

您要确保查询仅使用索引,因此请确保索引涵盖您选择的所有字段。此外,由于它涉及范围查询,因此需要在索引中首先使用venid,因为它被查询为常量。因此我会像这样创建和索引:

ALTER TABLE events ADD INDEX indexNameHere (venid, date, time);

使用此索引,完成查询所需的所有信息都在索引中。这意味着,希望存储引擎能够获取信息而无需在表内部实际查找。但是,MyISAM可能无法执行此操作,因为它不会将数据存储在索引的叶子中,因此您可能无法获得所需的速度增加。如果是这种情况,请尝试创建表的副本,并在副本上使用InnoDB引擎。在那里重复相同的步骤,看看你是否有显着的速度提升。 InnoDB 确实将字段值存储在索引叶子中,并允许覆盖索引。

现在,希望您在解释查询时看到以下内容:

mysql> EXPLAIN SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date;

id  select_type table  type  possible_keys        key       [..]  Extra
1   SIMPLE   events range date_idx, indexNameHere indexNameHere   Using index, Using where

答案 1 :(得分:2)

尝试添加一个跨越venid和日期(或反过来,或两者兼有......)的密钥

答案 2 :(得分:2)

我认为6M行表应该能够通过非常正常的技术进行优化。

我假设你有一个专用的数据库服务器,并且它有一个合理数量的ram(比如最低8G)。

您需要确保已经调整了mysql以有效地使用您的ram。如果您运行的是32位操作系统,请不要。如果你正在使用MyISAM,请调整你的密钥缓冲区,使用你公羊的一个显着比例,但不要太多。

在任何情况下,您都希望在生产级硬件上运行重复的性能测试。

答案 3 :(得分:1)

尝试在venid列上添加索引。