2010-10-02 167 views
2

我有一張擁有數百萬條記錄的大表。MySQL是否在創建新索引時使用現有索引?

Table `price` 
------------ 
id 
product 
site 
value 

該表是全新的,並且沒有創建索引。

我再發放給新的索引創建與下面的查詢請求:

CREATE INDEX ix_price_site_product_value_id ON price (site, product, value, id); 

這花了很長很長的時間,我最後一次檢查跑了5000+秒,因爲機器的。

我想知道如果我發出另一個索引創建,它會使用過程計算中的現有索引?如果是這樣,以什麼形式?

下運行查詢1:

CREATE INDEX ix_price_product_value_id ON price (product, value, id); 

下運行查詢2:如果你使用MySQL 5.1版,而InnoDB存儲引擎

CREATE INDEX ix_price_value_id ON price (value, id); 

回答

4

,您可能需要使用InnoDB Plugin 1.0,它支持一個稱爲Fast Index Creation的新功能。這允許存儲引擎創建索引而不復制整個表的內容。

概述InnoDB的插件的:

5.1版本開始,MySQL AB公司推動了一個「可插拔的」存儲引擎架構,它允許多個存儲引擎被加入到MySQL的想法。然而,目前大多數用戶只訪問由MySQL AB分發的存儲引擎,並鏈接到二進制(可執行)版本。從2001年開始,MySQL AB已經發布了InnoDB事務存儲引擎及其版本(包括源代碼和二進制代碼)。從MySQL版本5.1開始,用戶可以換出一個版本的InnoDB並使用另一個版本。

來源:Introduction to the InnoDB Plugin

概述快速創建索引:

在MySQL版本到5.0,增加或與現有數據表刪除索引可如果表很慢有很多行。 CREATE INDEXDROP INDEX命令通過創建一個用請求的索引集定義的新的空表來工作。然後,它將現有的行逐一複製到新表中,隨着更新索引進行更新。以這種方式將條目插入到索引中(鍵值未排序)需要對索引節點進行隨機訪問,並且遠非最佳。在複製原始表中的所有行之後,將刪除舊錶,並使用原始表的名稱重命名該副本。

從版本5.1開始,MySQL允許存儲引擎創建或刪除索引而不復制整個表的內容。然而,MySQL版本5.1中的標準內置InnoDB並沒有利用這種能力。然而,使用InnoDB插件,用戶在大多數情況下可以比以前的版本更有效地添加和刪除索引。

...

更改聚簇索引需要複製數據,即使使用InnoDB插件也是如此。但是,使用InnoDB插件添加或刪除輔助索引要快得多,因爲它不涉及複製數據。

來源:Overview of Fast Index Creation

+0

聽起來很酷。如何檢查機器是否安裝了InnoDB插件? – Pentium10 2010-10-02 10:06:19

+0

在你的MySQL客戶端執行'SELECT VERSION()'。你的MySQL服務器是v5.1 +嗎? – 2010-10-02 10:07:20

+0

我的版本是:5.1.33-community-log – Pentium10 2010-10-02 10:08:18

5

我想知道如果我發出另一個創建索引時,將使用現有的索引的過程中計算?如果是這樣,以什麼形式?

不,不會。

理論上,(site, product, value, id)上的索引具有在這些字段的任何子集(包括(product, value, id)(value, id)上的索引)上建立索引所需的所有內容。

但是,不支持從輔助索引構建索引。

首先,MySQL不支持快速全索引掃描(即以物理順序而不是邏輯掃描索引),因此使索引訪問路徑比讀取表更加昂貴。這不是InnoDB的問題,因爲表本身總是聚集在一起的。

其次,這些索引中的記錄訂單是完全不同的,因此無論如何都需要對記錄進行排序。

但是,MySQL索引創建速度的主要問題在於,它會在現場生成訂單(只需將記錄逐個插入B-Tree),而不是使用預分類源。正如@丹尼爾提到的那樣,快速索引創建解決了這個問題。它可作爲5.1的插件提供,並預裝在5.5中。

+0

我肯定會閱讀更多關於選擇所有東西的引擎等,以及索引創建速度如何在不同的數據類型上工作。也許這應該是您的博客上新帖子的新材料。你說什麼? – Pentium10 2010-10-02 13:43:25

+0

@ Pentium10:一個好主意。 – Quassnoi 2010-10-02 14:37:39