MySQL的速度非常慢,有2000万条记录

时间:2015-04-22 15:23:28

标签: mysql

执行简单的查询,例如

    select state, count(state) as cnt from big_data where status=0 group by state

需要大约20秒。这是我的表格def:

    CREATE TABLE `NewTable` (`id`  bigint(22) NOT NULL AUTO_INCREMENT ,
                             `city`  varchar(32) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ,
                             `state`  varchar(2) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ,
                             `miles_away`  int(5) NOT NULL ,
                             `member_id`  int(11) NOT NULL ,
                             `gender`  varchar(17) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ,
                             `profile`  varchar(128) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL ,
                             `status`  varchar(1) CHARACTER SET latin1                           

    COLLATE latin1_swedish_ci NOT NULL ,
    PRIMARY KEY             ( `id`, 
                              `city`,
                              `state`, 
                              `miles_away`, 
                              `member_id`, 
                              `gender`, 
                              `profile`, 
                              `status`),
    UNIQUE INDEX `id` (`id`) USING BTREE ,
    UNIQUE INDEX `profile` (`profile`) USING BTREE ,
    INDEX `city` (`city`) USING BTREE ,
    INDEX `state` (`state`) USING BTREE ,
    INDEX `miles_away` (`miles_away`) USING BTREE ,
    INDEX `member_id` (`member_id`) USING BTREE ,
    INDEX `gender` (`gender`) USING BTREE ,
    INDEX `status` (`status`) USING BTREE)
    ENGINE=InnoDB
    DEFAULT CHARACTER SET=latin1 COLLATE=latin1_swedish_ci
    AUTO_INCREMENT=12889691
    ROW_FORMAT=COMPACT;

即使是基于主键的简单id查找也需要很长时间。我的服务器有72个核心(第4代Xeon ES2690和64GB RAM)

以下是解释的截图:

multi threads http://gaysugardaddyfinder.com/shot.PNG

帮助!

1 个答案:

答案 0 :(得分:1)

使用EXPLAIN显示执行计划。

参考:https://dev.mysql.com/doc/refman/5.5/en/using-explain.html

为获得最佳性能,请提供合适的索引,以便优化程序可以避免使用文件排序"满足GROUP BY的操作。

我建议:

CREATE INDEX `NewTableIX1` ON `NewTable` (`status`,`state`)

(我建议,因为您的查询在status列中包含了一个等式谓词,并且它正在state列上按操作执行分组。使用这个新索引,我可以期望EXPLAIN输出显示它使用新索引,并且还显示完全从索引满足查询 - "使用索引"在Extra中显示EXPLAIN输出的列。)

定义了这个新索引后,status列上的单独索引是多余的,可以删除。

<强>后续

由于id是UNIQUE而非NULL,因此它可以作为表的PRIMARY KEY。 PRIMARY KEY不需要包含表中的每一列。 (二级索引将与表本身一样大,因为PRIMARY KEY将在每个索引中存储&#34;指针&#34;返回到群集索引。)

如果这是我的桌子,我会替换它:

PRIMARY KEY             ( `id`, 
                          `city`,
                          `state`, 
                          `miles_away`, 
                          `member_id`, 
                          `gender`, 
                          `profile`, 
                          `status`),
UNIQUE INDEX `id` (`id`) USING BTREE ,

只有这个:

PRIMARY KEY (`id`)

(我创建新表,并复制旧表中的所有数据。)