[英]Does MySQL use existing indexes on creating new indexes?
我有一張包含數百萬條記錄的大桌子。
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旁邊:
CREATE INDEX ix_price_value_id ON price (value, id);
我想知道如果我發出另一個索引創建,它會在進程計算中使用現有索引嗎? 如果是這樣的形式?
不,它不會。
從理論上講, (site, product, value, id)
上的索引具有在這些字段的任何子集上構建索引所需的一切(包括(product, value, id)
和(value, id)
上的索引)。
但是,不支持從二級索引構建索引。
首先, MySQL
不支持快速全索引掃描(即以物理順序掃描索引而不是邏輯),因此使索引訪問路徑比表讀取更昂貴。 這對InnoDB
來說不是問題,因為表本身總是聚集的。
其次,這些索引中的記錄順序完全不同,因此無論如何都需要對記錄進行排序。
但是, MySQL
索引創建速度的主要問題是它在站點上生成順序(只是將記錄逐個插入到B-Tree
)而不是使用預先排序的源。 正如@Daniel所提到的,快速索引創建解決了這個問題。 它作為5.1
的插件提供,並預裝在5.5
。
如果您使用的是MySQL 5.1版和InnoDB存儲引擎,您可能需要使用InnoDB Plugin 1.0 ,它支持一項名為Fast Index Creation的新功能。 這允許存儲引擎創建索引而不復制整個表的內容。
InnoDB插件概述:
從版本5.1開始,MySQL AB推出了“可插拔”存儲引擎架構的概念,該架構允許將多個存儲引擎添加到MySQL。 但是,目前大多數用戶只訪問由MySQL AB分發的那些存儲引擎,並鏈接到二進制(可執行)版本。
自2001年以來,MySQL AB已經發布了InnoDB事務存儲引擎及其版本(源代碼和二進制代碼)。 從MySQL 5.1版開始,用戶可以交換一個版本的InnoDB並使用另一個版本。
來源: InnoDB插件簡介
快速索引創建概述:
在高達5.0的MySQL版本中,如果表有很多行,在具有現有數據的表上添加或刪除索引可能會非常慢。
CREATE INDEX
和DROP INDEX
命令通過創建使用請求的索引集定義的新空表來工作。 然后,它將現有行逐個復制到新表,隨時更新索引。 以這種方式將條目插入到索引中,其中鍵值未被排序,需要隨機訪問索引節點,並且遠非最佳。 復制原始表中的所有行后,將刪除舊表,並使用原始表的名稱重命名該副本。從版本5.1開始,MySQL允許存儲引擎創建或刪除索引,而無需復制整個表的內容。 但是,MySQL版本5.1中的標准內置InnoDB沒有利用此功能。 但是,使用InnoDB插件,用戶在大多數情況下可以比以前的版本更有效地添加和刪除索引。
...
更改聚簇索引需要復制數據,即使使用InnoDB插件也是如此。 但是,使用InnoDB插件添加或刪除輔助索引要快得多,因為它不涉及復制數據。
來源: 快速索引創建概述
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.