在单个分区中查询记录非常慢

时间:2019-02-12 16:37:36

标签: mysql database-partitioning

我有一个分区的大表(超过20亿条记录)。每个分区包含大约5亿条记录。我最近从物理硬件转移到了AWS,我使用了mysqldump来备份和还原MySQL数据。我最近还创建了一个新分区(p108)。从旧分区(在旧服务器上创建)中查询数据正在正常,非常快速地运行,并在几秒钟内返回了数据。但是,查询新创建的分区(p108)中的记录非常慢-分钟。

show create table结果

CREATE TABLE `termusage` 
  ( 
     `id`            BIGINT(20) NOT NULL auto_increment, 
     `terminal`      BIGINT(20) DEFAULT NULL, 
     `date`          DATETIME DEFAULT NULL, 
     `dest`          VARCHAR(255) DEFAULT NULL, 
     `feattrans`     BIGINT(20) DEFAULT NULL, 
     `cost_type`     TINYINT(4) DEFAULT NULL, 
     `cost`          DECIMAL(16, 6) DEFAULT NULL, 
     `gprsup`        BIGINT(20) DEFAULT NULL, 
     `gprsdown`      BIGINT(20) DEFAULT NULL, 
     `duration`      TIME DEFAULT NULL, 
     `file`          BIGINT(20) DEFAULT NULL, 
     `custcost`      DECIMAL(16, 6) DEFAULT '0.000000', 
     `invoice`       BIGINT(20) NOT NULL DEFAULT '99999999', 
     `carriertrans`  BIGINT(20) DEFAULT NULL, 
     `session_start` DATETIME DEFAULT NULL, 
     `session_end`   DATETIME DEFAULT NULL, 
     `mt_mo`         VARCHAR(4) DEFAULT NULL, 
     `grps_rounded`  BIGINT(20) DEFAULT NULL, 
     `gprs_rounded`  BIGINT(20) DEFAULT NULL, 
     `country`       VARCHAR(25) DEFAULT NULL, 
     `network`       VARCHAR(25) DEFAULT NULL, 
     `ctn`           VARCHAR(20) DEFAULT NULL, 
     `pricetrans`    BIGINT(20) DEFAULT NULL, 
     PRIMARY KEY (`id`, `invoice`), 
     KEY `idx_terminal` (`invoice`, `terminal`), 
     KEY `idx_feattrans` (`invoice`, `feattrans`), 
     KEY `idx_file` (`invoice`, `file`), 
     KEY `termusage_carriertrans_idx` (`carriertrans`), 
     KEY `idx_ctn` (`invoice`, `ctn`), 
     KEY `idx_pricetrans` (`invoice`, `pricetrans`) 
  ) 
engine=innodb 
auto_increment=17449438880 
DEFAULT charset=latin1 
/*!50500 PARTITION BY RANGE  COLUMNS(invoice) 
(PARTITION p103 VALUES LESS THAN (621574) ENGINE = InnoDB, 
 PARTITION p104 VALUES LESS THAN (628214) ENGINE = InnoDB, 
 PARTITION p106 VALUES LESS THAN (634897) ENGINE = InnoDB, 
 PARTITION p107 VALUES LESS THAN (649249) ENGINE = InnoDB, 
 PARTITION p108 VALUES LESS THAN (662763) ENGINE = InnoDB, 
 PARTITION plast VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */ 

我使用以下查询创建了分区p108

ALTER TABLE termusage reorganize partition plast 
INTO        ( partition p108 VALUES less than (662763), 
              partition plast VALUES less than maxvalue )

我可以看到文件termusage#p#p108.ibd看起来是“正常”的,并且数据在那里,因为我可以从查询中获得结果。

information_schema.PARTITIONS在表格中显示以下内容-表示存在某种问题

Name    Pos Rows        Avg Data Length Method
p103    1   412249206   124 51124371456 RANGE COLUMNS
p104    2   453164890   133 60594061312 RANGE COLUMNS
p106    3   542767414   135 73562849280 RANGE COLUMNS
p107    4   587042147   129 76288098304 RANGE COLUMNS
p108    5   0           0   16384       RANGE COLUMNS
plast   6   0           0   16384       RANGE COLUMNS

如何修复分区?

已更新

解释好查询

# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1, SIMPLE, t, p107, ref, idx_terminal,idx_feattrans,idx_file,idx_ctn,idx_pricetrans, idx_terminal, 17, const,const, 603, 100.00, Using index condition; Using temporary; Using filesort

解释查询不正确

# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra
1, SIMPLE, t, p108, ALL, idx_terminal,idx_feattrans,idx_file,idx_ctn,idx_pricetrans, , , , 1, 100.00, Using where; Using temporary; Using filesort

1 个答案:

答案 0 :(得分:1)

对于将来的读者,通过运行ALTER TABLE ... ANALYZE PARTITION p108解决了该问题。

指导优化器选择最佳读取表方式的表和索引统计信息已过时。通常,使用ANALYZE来确保在加载或删除大量数据后更新这些统计信息。