查询单个分区记录很慢

Querying record in a single partition very slow

我有一个很大的 table(超过 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 并且看起来是 "normal" 并且数据在那里,因为我可以从查询中获得结果。

information_schema.PARTITIONS 显示 table 的以下内容 - 这表明存在某种问题

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

对于未来的读者,问题已由 运行 ALTER TABLE ... ANALYZE PARTITION p108 解决。

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