There are multiple ways to retrieve the same index information...
SHOW INDEXES FROM myTable;
SHOW INDEXES IN myTable;
SHOW INDEXES FROM myTable IN myDB;
SHOW INDEXES IN myTable FROM myDB;
SHOW INDEXES FROM myDB.myTable;
SHOW INDEXES IN myDB.myTable;
SHOW INDEXES FROM myTable WHERE ...
SHOW INDEX FROM myTable;
SHOW INDEX IN myTable;
SHOW INDEX FROM myTable IN myDB;
SHOW INDEX IN myTable IN myDB;
SHOW INDEX FROM myDB.myTable;
SHOW INDEX IN myDB.myTable;
SHOW INDEX FROM myTable WHERE ...
SHOW KEYS FROM myTable;
SHOW KEYS IN myTable;
SHOW KEYS FROM myTable IN myDB;
SHOW KEYS IN myTable IN myDB;
SHOW KEYS FROM myDB.myTable;
SHOW KEYS IN myDB.myTable;
SHOW KEYS FROM myTable WHERE ...
TABLE
NON_UNIQUE
KEY_NAME
SEQ_IN_INDEX
COLUMN_NAME
COLLATION
CARDINALITY
SUB_PART
PACKED
NULL
INDEX_TYPE
COMMENT
INDEX_COMMENT
VISIBLE
EXPRESSION
Table Name
1 = Duplicates allowed; 0 = No Duplicates NOT allowed
Index Name. Primary Key is always PRIMARY
Shows order of columns in a multi-column index
Column Name (NULL for expression based indexes)
A = Ascending; B = Descending; NULL = not sorted
An estimated number of unique values in the index
NULL if entire column is indexed otherwise shows number of indexed characters for partial column index
NULL if not Packed
YES = NULLs allowed; NULL = NULLs NOT allowed
BTREE, HASH, RTREE, FULLTEXT
COMMENT attribute from index creation
YES = Visible to Query Optimizer; NO = Invisible to Query Optimizer
Expression used for expression based indexes
ALTER TABLE mytable ADD INDEX(mycolumn);
or...
CREATE INDEX myindex ON mytable(mycolumn);
Index creation will be online where possible but may resort to a blocking (copy and switch) approach if necessary.
To force an online rebuild (and fail with an error if it's not possible)...
CREATE INDEX myindex ON mytable(mycolumn) ALGORITHM = INPLACE;
If you cannot change the table structure to include an extra visible column to use as a PRIMARY KEY (perhaps it's a third party application), you can make use of the INVISIBLE COLUMN feature.
ALTER TABLE mytable
ADD COLUMN _mypk BIGINT UNSIGNED NOT NULL AUTO_INCREMENT INVISIBLE,
ADD PRIMARY KEY (_mypk);
This is Oracle's recommended approach.MySQL automatically ensures auto-increment values don’t collide on different nodes.The leading underscore is arbitrary; you can call the key by any valid name.An alternate approach...
ALTER TABLE mytable
ADD COLUMN _mypk BINARY(16) NOT NULL DEFAULT (UUID_TO_BIN(UUID())) INVISIBLE,
ADD PRIMARY KEY (_mypk);
A UUID (Universally Unique Identifier) is a 128-bit value designed to be unique across space and time without relying on a central authority or database sequence. This might be the right choice if the system might scale across multiple clusters (i.e. where MySQL is unable to coordinate auto-incrfement values to avoid duplicates).The leading underscore is arbitrary; you can call the key by any valid name.DROP INDEX myindex ON mytable;
To enable statistics collection...
SET GLOBAL userstat=1;
By default, statistics are not collected.SELECT *
FROM INFORMATION_SCHEMA.TABLE_STATISTICS;
SELECT *
FROM INDEX_STATISTICS;
Report Unused Indexes...
SELECT DISTINCT s.TABLE_SCHEMA,
s.TABLE_NAME,
s.INDEX_NAME
FROM information_schema.statistics `s`
LEFT JOIN information_schema.index_statistics INDXS ON (s.TABLE_SCHEMA = INDXS.TABLE_SCHEMA
AND s.TABLE_NAME=INDXS.TABLE_NAME
AND s.INDEX_NAME=INDXS.INDEX_NAME)
WHERE INDXS.TABLE_SCHEMA IS NULL;
Performing an online rebuild of a table will rebuild (and thus defragment) the associated indexes....
ALTER TABLE mytable ENGINE=INNODB;