MySQL 索引大于存储的数据

标签 mysql database optimization indexing innodb

我有一个包含以下统计信息的数据库

Tables     Data   Index   Total
11     579,6 MB  0,9 GB  1,5 GB

因此,正如您所见,索引几乎大了 2 倍。有一个表有大约 700 万行,至少占据了其中的 99%。

我也有两个非常相似的索引

a) UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`),
b) KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`)

更新:这是最大表的表定义(至少在结构上)

CREATE TABLE `invoices` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `customer_id` int(10) unsigned NOT NULL,
  `order_no` varchar(10) default NULL,
  `invoice_no` varchar(20) default NULL,
  `customer_no` varchar(20) default NULL,
  `name` varchar(45) NOT NULL default '',
  `archived` tinyint(4) default NULL,
  `invoiced` tinyint(4) default NULL,
  `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `group` int(11) default NULL,
  `customer_group` int(11) default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `idx_customer_invoice` (`customer_id`,`invoice_no`),
  KEY `idx_time` (`time`),
  KEY `idx_order` (`order_no`),
  KEY `idx_customer_invoice_order` (`customer_id`,`invoice_no`,`order_no`)
) ENGINE=InnoDB AUTO_INCREMENT=9146048 DEFAULT CHARSET=latin1 |

更新 2:

mysql> show indexes from invoices;
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table    | Non_unique | Key_name                   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| invoices |          0 | PRIMARY                    |            1 | id          | A         |     7578066 |     NULL | NULL   |      | BTREE      |         |
| invoices |          0 | idx_customer_invoice       |            1 | customer_id | A         |          17 |     NULL | NULL   |      | BTREE      |         |
| invoices |          0 | idx_customer_invoice       |            2 | invoice_no  | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_time                   |            1 | time        | A         |      541290 |     NULL | NULL   |      | BTREE      |         |
| invoices |          1 | idx_order                  |            1 | order_no    | A         |        6091 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            1 | customer_id | A         |          17 |     NULL | NULL   |      | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            2 | invoice_no  | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
| invoices |          1 | idx_customer_invoice_order |            3 | order_no    | A         |     7578066 |     NULL | NULL   | YES  | BTREE      |         |
+----------+------------+----------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

我的问题是:

  1. 有没有办法在 MySQL 中找到未使用的索引?
  2. 是否存在影响索引大小的常见错误?
  3. 可以安全地删除 indexA 吗?
  4. 如何衡量每个指标的规模?我得到的只是所有索引的总和。

最佳答案

您可以删除索引 A,因为正如您所注意到的,它是另一个索引的子集。并且可以在不中断正常处理的情况下执行此操作。

索引文件的大​​小本身并不令人担忧,净 yield 很容易成为正数。换句话说,索引的实用性和值(value)不应该因为它会产生一个大文件而被打折。

索引设计是一门复杂而精妙的艺术,涉及对查询优化器解释的深刻理解和广泛的测试。但是一个常见的错误是在索引中包含的字段太少以使其更小。另一种是用不充分或代表性不足的数据测试指标。

关于MySQL 索引大于存储的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5713339/

相关文章:

MySQL 子选择性能问题?

c++ - 灰度双线性 block 提取 - SSE 优化

mysql - 在 MySql 工作台中将列设置为时间戳?

java - 对 web.xml 中的 <security-role> 感到困惑

php - MYSQli 选择不工作

php - 需要一个高效的 mysql 数据库模式来存储积分/评级

database - 开源 Virtuoso DB 或任何特定图形的大小

mysql - 为了获得最佳性能,是将单个数据划分到单独的表中还是保留在单个表中更好

php - 迁移 PHP 5.2 网站

MySQL表关系以及如何查询Key/value表