2011-04-19 38 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)不是,所以你可能會失去唯一性約束,當你刪除它。沒有?