Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql在600万行表上的性能_Mysql_Performance_Indexing - Fatal编程技术网

Mysql在600万行表上的性能

Mysql在600万行表上的性能,mysql,performance,indexing,Mysql,Performance,Indexing,有一天,我怀疑我将不得不学习hadoop并将所有这些数据传输到一个非结构化数据库,但我惊讶地发现,在如此短的时间内,性能会显著下降 我有一个mysql表,只有不到600万行。 我正在对这个表进行一个非常简单的查询,我相信我已经准备好了所有正确的索引 问题是 SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date 从事件中选择日期、时间,其中venid='47975'和日期>='2

有一天,我怀疑我将不得不学习hadoop并将所有这些数据传输到一个非结构化数据库,但我惊讶地发现,在如此短的时间内,性能会显著下降

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

问题是

SELECT date, time FROM events WHERE venid='47975' AND date>='2009-07-11' ORDER BY date 从事件中选择日期、时间,其中venid='47975'和日期>='2009-07-11'按日期排序 解释返回

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 id选择\u类型表类型可能的\u键\u长度参考行额外 1个简单更新显示范围日期\u idx日期\u idx 7 NULL 648997使用where 因此,就我所知,我正在使用正确的索引,但是这个查询需要11秒才能运行

数据库是MyISAM,phpMyAdmin说表是1.0GiB

有什么想法吗

编辑:
date_idx是日期和venid列的索引。这应该是两个独立的索引吗?

尝试添加一个跨越venid和date的键(或者相反,或者两者都是…)

尝试在
venid
列上放置一个索引。

您想要确保的是查询只使用索引,因此确保索引覆盖您选择的所有字段。此外,由于涉及范围查询,您需要在索引中首先使用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

我可以想象,一个6M行的桌子应该能够用非常普通的技术进行优化

我假设您有一个专用的数据库服务器,并且它有相当数量的ram(比如说,最小8G)

您需要确保您已经调优了mysql,以便有效地使用ram。如果您运行的是32位操作系统,请不要。如果您使用的是MyISAM,请调整您的密钥缓冲区,使其在ram中占一定比例,但不要过多


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

我刚刚编辑了我的条目,date\u idx在date和venid字段上。对不起,我最初没有放进去。当你说“添加键”时,你是指索引吗?我编辑了我的条目,说明date_idx同时位于date和venid字段上。谢谢Michael,我没有意识到所选字段也应该被索引。干杯。索引上没有选择字段会使系统更加僵化吗。任何新的预测都必须添加到索引中。这是正确的方法吗?+1:覆盖索引是必要的。有了仔细的索引和仔细的查询,6mm行就没什么大不了的了。太棒了!!非常感谢。我没有意识到我需要用索引覆盖所选字段。我认为这正是需要索引的WHERE字段。如果你还记得的话,使用索引的新查询的执行时间是多少?@pedalpete我问的问题与Justin相同。很抱歉,@JustinKrause(和其他人)的回复太晚了,你的评论是在最初的问题几年后提出的。在修复了索引之后,我相信查询时间不到0.4秒。它的速度惊人,而且也不是在专用服务器上。这是一个中等大小的盒子,当时没有什么大的。我不记得是linode还是我不久就切换到了linode。您的解释查询说它必须扫描648997行(可能它没有足够有效地使用索引。如果是我,我会单独索引列)。实际返回了多少行?谢谢@MarkR,很抱歉回复太晚。这是我创建的第二个网站,所以我不知道有专门的数据库服务器或类似的东西。我在同一个盒子上运行了几年,所有进程都在同一个盒子上。没有问题,我很惊讶MySQL能够扩展到800多万行。当旧数据到达那个点时,我会将其归档。