2011-04-19 39 views
12

数据大我有以下统计数据库MySQL的指数大于存储

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. 如何衡量每个索引的大小?我所得到的是所有指标的总和。
+0

如果你可以为任何大型表运行一些'show create table'并发布输出将会很有帮助。 – 2011-04-19 08:08:15

回答

10

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

索引文件的大​​小本身并不令人担忧,并且很容易就可以得出这样的结论:净收益是正数。换句话说,索引的有用性和价值不应该被打折,因为它会导致一个大文件。

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

+3

我可以就“微妙的艺术”达成一致。 – 2011-04-19 08:37:05

1

有没有办法在MySQL中查找未使用的索引?

当试图优化您的查询时,数据库引擎优化器将选择一个合适的索引。根据您最后收集的索引统计信息,所选的索引会有所不同。由于新的数据重新分区,未使用的索引可能突然被使用。

可以安全地删除indexA吗?

我会说是的,如果indexA和indexB是B-Tree索引。这是因为以相同顺序的相同列开始的索引将具有相同的结构。

+0

对于另外两个问题,我不确定我能否正确回答。 – Benoit 2011-04-19 08:08:20

+1

所有索引都是B-树 – 2011-04-19 08:21:07

1

使用

show indexes from table; 

定义哪些索引你有一个特定的表。基数会告诉你的索引是多么有用。

您可以安全地删除索引(它不会破坏表),但要小心:某些查询可能执行速度较慢。首先,你应该分析你的查询来决定你是否需要某个索引。

虽然我不认为你可以找出特定索引的数据长度。

但是,我想你可能认为如果索引长度大于数据长度两次是不正常的......呃,你错了。所有的索引都可能是有用的;)如果你有一个提供大量信息的表,并且你必须在大量的列上搜索它,很容易这个表的索引大小会增加两倍表格数据。

+0

你能指定基数如何对应于有用性吗?索引在那里是有原因的,查询对这个表的性能对应用程序是非常重要的。 – 2011-04-19 08:23:11

+0

但是,我很高兴听到它至少没有异常...... P – 2011-04-19 08:24:17

+0

在官方文档中说:“基数越高,MySQL进行连接时使用索引的机会就越大”。实际上,这意味着这个列将被用于更多次的连​​接,然后是其他基数较低的连接。基数评估是基于统计。究竟如何?那么......我不知道:)如果基数很高,这个指数消耗更多的音量,因为“基数是指数中唯一值数量的估计值”。 – Nemoden 2011-04-19 08:29:22

0
  1. 指数A可以删除,因为有一个 indexB包括指数A
  2. 食指长度是什么样的影响 字段类型和列长度
  3. 使用:从INFORMATION_SCHEMA.TABLES 其中

    选择index_length table_name ='your_table_name'和 table_schema ='your_db_name';

    让你的表index_length

+0

3.这给了我一个号码,1003831296,这是什么意思? – 2011-04-19 08:33:21

+0

@Peter Lindqvist索引长度为1003831296B;你也可以使用显示表状态,如“your_table_name” – Neo 2011-04-19 08:41:07

+0

嗯,我希望看到个别指数的大小。 – 2011-04-19 08:43:06

6

我可能是错的,但第一个指标(idx_customer_invoice)是唯一的,第二个(idx_customer_invoice_order)不是,所以你可能会失去唯一性约束,当你删除它。没有?