Mysql

MySQL:如果不存在則創建索引

  • May 25, 2021

如果 MySQL 不存在,有沒有辦法在它中創建索引?

MySQL 不支持明顯的格式:

CREATE INDEX IF NOT EXISTS index_name ON table(column)
ERROR 1064 (42000): You have an error in your SQL syntax;...

MySQL版本(mysql -V)是5.1.48,但我認為MySQLCREATE INDEX IF NOT EXIST在其所有版本中都缺乏能力。

只有在 MySQL 中不存在索引時才創建索引的正確方法是什麼?

該功能不存在。有兩件事要記住:

無論如何創建索引

您可以通過創建索引的方式生成索引,而無需提前檢查索引是否存在。例如,您可以執行以下命令:

ALTER TABLE table_name ADD INDEX (column_to_index);
ALTER TABLE table_name ADD INDEX (column_to_index);

這肯定會在不檢查的情況下創建兩個索引。每個索引都將被分配一個名稱(可能是 column_to_index,column_to_index_1)。當然,您正試圖避免這種情況。

首先檢查 INFORMATION_SCHEMA

這是 INFORMATION_SCHEMA.STATISTICS 的佈局:

mysql> show create table statistics\G
*************************** 1. row ***************************
      Table: STATISTICS
Create Table: CREATE TEMPORARY TABLE `STATISTICS` (
 `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
 `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
 `TABLE_NAME` varchar(64) NOT NULL DEFAULT '',
 `NON_UNIQUE` bigint(1) NOT NULL DEFAULT '0',
 `INDEX_SCHEMA` varchar(64) NOT NULL DEFAULT '',
 `INDEX_NAME` varchar(64) NOT NULL DEFAULT '',
 `SEQ_IN_INDEX` bigint(2) NOT NULL DEFAULT '0',
 `COLUMN_NAME` varchar(64) NOT NULL DEFAULT '',
 `COLLATION` varchar(1) DEFAULT NULL,
 `CARDINALITY` bigint(21) DEFAULT NULL,
 `SUB_PART` bigint(3) DEFAULT NULL,
 `PACKED` varchar(10) DEFAULT NULL,
 `NULLABLE` varchar(3) NOT NULL DEFAULT '',
 `INDEX_TYPE` varchar(16) NOT NULL DEFAULT '',
 `COMMENT` varchar(16) DEFAULT NULL,
 `INDEX_COMMENT` varchar(1024) NOT NULL DEFAULT ''
) ENGINE=MEMORY DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql>

您可以只按名稱查詢索引是否存在。例如,在你執行之前

CREATE INDEX index_name ON mytable(column);

你需要跑

SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_schema=DATABASE() AND table_name='mytable' AND index_name='index_name';

如果 IndexIsThere 為 0,則可以在索引中創建。也許您可以編寫一個儲存過程來在您選擇的表上創建索引。

DELIMITER $$

DROP PROCEDURE IF EXISTS `adam_matan`.`CreateIndex` $$
CREATE PROCEDURE `adam_matan`.`CreateIndex`
(
   given_database VARCHAR(64),
   given_table    VARCHAR(64),
   given_index    VARCHAR(64),
   given_columns  VARCHAR(64)
)
BEGIN

   DECLARE IndexIsThere INTEGER;

   SELECT COUNT(1) INTO IndexIsThere
   FROM INFORMATION_SCHEMA.STATISTICS
   WHERE table_schema = given_database
   AND   table_name   = given_table
   AND   index_name   = given_index;

   IF IndexIsThere = 0 THEN
       SET @sqlstmt = CONCAT('CREATE INDEX ',given_index,' ON ',
       given_database,'.',given_table,' (',given_columns,')');
       PREPARE st FROM @sqlstmt;
       EXECUTE st;
       DEALLOCATE PREPARE st;
   ELSE
       SELECT CONCAT('Index ',given_index,' already exists on Table ',
       given_database,'.',given_table) CreateindexErrorMessage;   
   END IF;

END $$

DELIMITER ;

這是一個範例執行(嘿,還記得這張表嗎?它來自您在 2012 年 6 月 27 日提出的問題):

mysql> show create table pixels\G
*************************** 1. row ***************************
      Table: pixels
Create Table: CREATE TABLE `pixels` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `type` varchar(30) DEFAULT NULL,
 `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `pixel_data` blob,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> call createindex('adam_matan','pixels','type_timestamp_id_ndx','type,timestamp,id');
Query OK, 0 rows affected (0.20 sec)

mysql> show create table pixels\G
*************************** 1. row ***************************
      Table: pixels
Create Table: CREATE TABLE `pixels` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `type` varchar(30) DEFAULT NULL,
 `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
 `pixel_data` blob,
 PRIMARY KEY (`id`),
 KEY `type_timestamp_id_ndx` (`type`,`timestamp`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> call createindex('adam_matan','pixels','type_timestamp_id_ndx','type,timestamp,id');
+-----------------------------------------------------------------------+
| CreateindexErrorMessage                                               |
+-----------------------------------------------------------------------+
| Index type_timestamp_id_ndx Already Exists on Table adam_matan.pixels |
+-----------------------------------------------------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

mysql>

試一試 !!!

引用自:https://dba.stackexchange.com/questions/24531