本頁面說明如何在 Cloud SQL 唯讀副本上新增及捨棄索引。雖然副本通常是唯讀,但有時您可能需要為報表建立資料表次要索引。Cloud SQL 提供一組預存程序,可管理這些索引。
術語
- 叢集索引。MySQL 資料表的主要索引,會實際排序磁碟上的資料列。在資料表上定義主鍵時,MySQL 會將其做為叢集索引。資料表只能有一個叢集索引。
- 次要索引:MySQL 資料表上的額外索引,可提升查詢效能。
索引的預存程序
Cloud SQL 的 mysql
結構定義包含兩個儲存程序,可用於在 MySQL 唯讀副本上新增及捨棄次要索引。請注意,雖然這些程序可以在主要來源執行個體上執行,但專為唯讀備用資源設計。
- mysql.addSecondaryIdxOnReplica
- 在資料庫中新增次要索引。這個預存程序是 CREATE INDEX DDL 陳述式的包裝函式。
參數:
idxType
- 要建立的索引類型。舉例來說,傳遞 UNIQUE 可建立專屬索引。idxName
- 索引名稱。tableName
- 資料表名稱,格式為 schema.name。idxDefinition
- 索引的定義。請勿加入外層括號。idxOption
- Any additional options to pass on index creation. 舉例來說,在 MySQL 8.0 中,選項可能會為隱形索引傳遞 INVISIBLE。
語法:
mysql.addSecondaryIdxOnReplica(idxType, idxName, tableName, idxDefinition, idxOption)
- mysql.dropSecondaryIdxOnReplica
- 會捨棄資料庫的次要索引。這個預存程序是 DROP INDEX DDL 陳述式的包裝函式。
參數:
idxName
- 索引名稱。tableName
- 資料表名稱,格式為 schema.name。idxOption
- Any additional options to pass when dropping an index. 例如 INPLACE 等演算法選項。
語法:
mysql.dropSecondaryIdxOnReplica(idxName, tableName, idxOption)
如需 idxType
和 idxOption
參數,請參閱 Cloud SQL 執行個體上執行的主要 MySQL 版本說明文件。
範例
正確用法
以下是程序的幾個呼叫範例。假設我們有一個資料表,定義如下。
CREATE TABLE sampletest.t1(
id int(10) unsigned NOT NULL AUTO_INCREMENT,
first_name varchar(64) NOT NULL,
last_name varchar(64) NOT NULL,
license_id int NOT NULL,
PRIMARY KEY (id),
KEY idx_fname (first_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
如要在 first_name
和 last_name
資料欄上建立名為 t1_fname_lname
的一般索引,請執行下列指令:
call mysql.addSecondaryIdxOnReplica('', 't1_fname_lname', 'sampletest.t1', 'first_name, last_name', '')
如果您也想在 license_id
資料欄上建立名為 t1_license_id
的專屬索引,並加上「unique license id」註解,請執行下列指令:
call mysql.addSecondaryIdxOnReplica('unique', 't1_license_id', 'sampletest.t1', 'license_id', 'comment \"unique license id\"')
接著,如要捨棄 t1_fname_lname 索引,請執行下列指令:
call mysql.dropSecondaryIdxOnReplica('t1_fname_lname', 'sampletest.t1', '')
不當使用
由於 idxDefinition 參數中的外層括號,以下嘗試在 first_name
和 last_name
資料欄上建立索引的作業會失敗。
call mysql.addSecondaryIdxOnReplica('', 't1_extra_parenthesis', 'sampletest.t1', '(first_name, last_name)', '')
您只能在客戶建立的資料表上新增索引。嘗試在 mysql.servers 資料表的 host 資料欄上建立索引時,會發生下列錯誤。
call mysql.addSecondaryIdxOnReplica('', 'idx_invalid', 'mysql.servers', 'host', '')
您只能使用 dropSecondaryIdxOnReplica
程序,捨棄先前使用 addSecondaryIdxOnReplica
程序建立的索引。舉例來說,以下呼叫會因現有 idx_fname
索引而失敗。
call mysql.dropSecondaryIdxOnReplica('idx_fname', 'sampletest.t1', '')
在這些程序呼叫中進行 SQL 插入會失敗。舉例來說,下列含有註解序列的 SQL 注入攻擊會失敗。
call mysql.addSecondaryIdxOnReplica(\"user 'a'@'%' --\", 'idx_fname', 'sampletest.t1', 'first_name', '')
同樣地,這個含有分隔符的 SQL 植入嘗試也會失敗。
call mysql.addSecondaryIdxOnReplica('', 'idx_fname', 'sampletest.t1', 'first_name', ';flush status')
重新建立唯讀備用資源
偶爾發生問題時,Cloud SQL 會從主要來源重新建立唯讀備用資源,以便快速復原執行個體。在重建作業前於讀取副本上建立的索引不會保留。客戶有責任使用唯讀副本上的預存程序,重新建立這些索引。