在划分MySQL表之后创建索引?

在划分MySQL表之后创建索引?,mysql,indexing,partitioning,Mysql,Indexing,Partitioning,我有2000万条记录的mysql表Stop_次 我正在为此表使用MyISAM存储引擎 我的桌子结构是 | agency_id | varchar(50) | NO | | NULL | | | trip_id | varchar(50) | NO | PRI | NULL | | | arrival_time | time | NO | | NULL |

我有2000万条记录的mysql表Stop_次

我正在为此表使用MyISAM存储引擎

我的桌子结构是

| agency_id           | varchar(50) | NO   |     | NULL    |       |
| trip_id             | varchar(50) | NO   | PRI | NULL    |       |
| arrival_time        | time        | NO   |     | NULL    |       |
| departure_time      | time        | NO   |     | NULL    |       |
| stop_id             | varchar(50) | NO   | PRI | NULL    |       |
| stop_sequence       | int(11)     | NO   | PRI | NULL    |       |
| route_id            | varchar(50) | NO   |     | NULL    |       |
| route_type          | int(5)      | NO   |     | NULL    |       |
+---------------------+-------------+------+-----+--------
show create table Stop_Times的输出为-

我有一个问题

select distinct trip_id, stop_sequence from Stop_Times where agency_id = ? and stop_id = ?
在对表进行分区之前,此查询花费了4-5分钟以上的时间

但是现在我已经把桌子分好了 按keystop_id进行分区

现在执行此查询需要2-3秒

我有另一个查询,后面是上面的查询-

select distinct(stop_id) from Stop_Times where agency_id = ? and trip_id = ? and stop_sequence > ? 
上述查询的解释输出为-

1   SIMPLE  Stop_Times  range   idx_Stop_Times  idx_Stop_Times  308 NULL    250 Using where; Using index; Using temporary
此查询需要90-150秒以上的时间

所以我的问题是我需要在trip\u id和stop\u序列上创建索引吗? 这会提高查询性能吗

我是否需要从InnoDB更改MyISAM中的存储引擎,因为一次有多个用户对此表执行许多readsselect查询

请数据库专家帮助我


谢谢

在机构id、行程id、停止顺序、停止id上创建覆盖索引。请注意索引中列的顺序很重要。使用不同的顺序可能不太有效。

也许您想考虑对这个数据集进行分词。 我维护了一个名为的工具,它可以并行查询所有碎片。您有一个自然切分密钥停止id,当前正在使用该id进行密钥分区。使用Shard查询,您可以将该列与哈希分区一起使用,从而获得函数等价性

使用Shard查询,您将创建250个数据库,每个数据库都具有表的相同副本。这相当于250个分区

分区消除 当您执行第一个查询时,Shard query将只将查询发送到包含给定stop_id的分区。这与MySQL分区修剪相同

大规模并行处理 对于第二个查询,Shard查询将根据您运行的gearman消息队列工作者的数量并行扫描分区。如果您有一台16核的机器,您可以在分区上获得16度的并行度,而不是MySQL对所有分区的单线程扫描

只要您的服务器有足够的资源来处理并行性,并行扫描就会大大提高速度。如果没有,您可以将数据拆分为N个服务器这是MPP中的一个大问题,在添加节点时,您将获得线性扩展。请记住,如果使用散列分区,添加或删除碎片需要重新加载所有数据,因此这种情况应该很少发生

一个警告:切分查询支持COUNTDISTINCT,但不支持SELECT DISTINCT…您可以简单地重写查询以使用GROUP BY:

问题1

select trip_id, stop_sequence from Stop_Times where agency_id = ? and stop_id = ? group by trip_id, stop_sequence;
问题2

select stop_id from Stop_Times where agency_id = ? and trip_id = ? and stop_sequence > ? group by stop_id;

谢谢马克的回复。我将按照给定的顺序创建索引。但是,由于表上的读取次数,我是否需要更改存储引擎?我认为您不需要更改引擎。添加索引后您获得了什么性能?嗨,Mark,我已经创建了索引,第二个查询大约需要30秒。我认为执行查询也太多了。如果您需要进一步的帮助,请更新您的问题以包括解释选择的输出。。。用于查询计划和显示表结构的创建表停止时间。您好,马克,我已用解释和显示创建更新了我的问题。。声明汉克斯·格林利昂。“分组”是不同的方式。我要试试这个。
select stop_id from Stop_Times where agency_id = ? and trip_id = ? and stop_sequence > ? group by stop_id;