MySQL: इंडेक्स बनाएँ यदि मौजूद नहीं है


62

क्या 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 है, लेकिन मुझे लगता है कि MySQL CREATE INDEX IF NOT EXISTमें इसके सभी संस्करणों में क्षमता का अभाव है ।

यदि केवल MySQL में यह पहले से मौजूद नहीं है, तो इंडेक्स बनाने का सही तरीका क्या है?

जवाबों:


36

वह कार्यक्षमता मौजूद नहीं है। ध्यान रखने योग्य दो बातें हैं:

वैसे भी इंडेक्स बनाएं

आप इस तरह से इंडेक्स जेनरेट कर सकते हैं कि इंडेक्स बिना जांचे ही बना दिया जाए कि इंडेक्स समय से पहले मौजूद है। उदाहरण के लिए, आप निम्नलिखित चला सकते हैं:

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 ;

यहां एक सैंपल रन (अरे इस टेबल को याद रखें? यह उस प्रश्न से है जो आपने 27 जून 2012 को पूछा था ):

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>

कोशिश करो !!!


37

SELECT IF()यदि आप प्रक्रिया नहीं करने का प्रयास कर रहे हैं, तो MySQL में कथन का उपयोग करने के साथ भी कुछ ऐसा ही है :

select if (
    exists(
        select distinct index_name from information_schema.statistics 
        where table_schema = 'schema_db_name' 
        and table_name = 'tab_name' and index_name like 'index_1'
    )
    ,'select ''index index_1 exists'' _______;'
    ,'create index index_1 on tab_name(column_name_names)') into @a;
PREPARE stmt1 FROM @a;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

यहाँ select ifइस प्रारूप है if (condition, true_case, false_case)select 'index index_1 exists'एक डमी मामला है। और _____उपनाम नाम की भूमिका निभाता है। यदि उपनाम नहीं किया गया है, तो स्तंभ नाम और पंक्ति दोनों शो index index_1 exists, जो और भी अधिक भ्रमित करते हैं। अधिक वर्णनात्मक होने के लिए आप उपयोग कर सकते हैं 'select ''index index_1 exists'' as _______;'


3

यदि आप सूचकांक का नाम देते हैं, तो यदि सूचकांक पहले से मौजूद है तो क्वेरी विफल हो जाएगी (MySQL 8.0 में परीक्षण किया गया):

ALTER TABLE `my_table` ADD INDEX `col_idx` (`col` DESC);

त्रुटि कोड: 1061. डुप्लीकेट कुंजी नाम 'col_idx';

तो आप केवल अपवाद को पकड़ सकते हैं और इसे अनदेखा कर सकते हैं, उदाहरण के लिए PHP में:

try {
    $db->query('ALTER TABLE `my_table` ADD INDEX `col_idx` (`col` DESC) VISIBLE;');
} catch (PDOException $ex) {
    if($exception->errorInfo[2] == 1061) {
        // Index already exists
    } else {
        // Another error occurred
    }
}

2
SELECT COUNT(*)
FROM information_schema.statistics
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'table_name' 
  AND INDEX_NAME = 'index_name'; 

मेरी क्वेरी आपको एक विशेष index_name के साथ एक मेज पर मौजूद अनुक्रमित की गिनती देगी। उस गिनती के आधार पर, आप तय कर सकते हैं कि CREATE INDEXकमांड जारी करना है या नहीं।

MySQL संस्करण 5.5 पर परीक्षण किया गया

MariaDB IF NOT EXISTSसिंटैक्स का समर्थन करता है । आप CREATE INDEX IF NOT EXISTSवहां उपयोग कर सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.