Official website document
MySQL :: MySQL 5.7 Reference Manual :: 8.3 Optimization and Indexes
Mysql optimization (from official documents) - eighth (index optimization series)
Table of contents
- Mysql optimization (from official documents) - eighth (index optimization series)
Optimization and Indexes
Correctly creating indexes often speeds up queries, but unnecessary indexes often just waste space and increase the overhead of inserting, updating, and deleting, because these operations need to update the index at the same time.
However, the index is not a panacea. In the following scenarios, the index will not be so useful:
- Small table, or large table, but all rows need to be requested
- When a request requires most of the rows in the table, continuous reading is often more efficient than indexing, because continuous reading reduces disk seek time.
1 Foreign Key Optimization
If you often read multiple columns in a table, then separate the least-accessed columns as a small table, and then use foreign keys to associate with the main table, so that you can read data as much as possible Reduce disk I/O reads and writes.
2 Column Indexes
-
Index Prefixes
Mysql allows only a part of some fields to be used as an index, which includes all
TEXT
andBLOB
fields, as in the following example:CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
It should be noted that for
CHAR, VARCHAR, TEXT
type fields, the length means the number of characters , but for non-string fields, such asBINARY, VARBINARY, BLOB
fields, the length means the number of bytes . -
FULLTEXT Indexes
This index is applicable to CHAR , VARCHAR , and TEXT columns, and the full-text index does not support prefixes, and only supports full-column indexes. Full-text indexing is useful when queries meet the following characteristics:
FULLTEXT
The query statement value requiresdocument ID
eithersearch rank
(grading??)FULLTEXT
The query statement sorts the queried results in descending order and has aLIMIT
statement selectiontop N
item. In this case, in order to use optimization, it must be ensured that the query statement does not haveWHERE
andORDER BY
only has one column.FULLTEXT
The query only getsCOUNT(*)
the result, and there is noWHERE
statement. If you need toWHERE
filter, pleaseWHERE
write asWHERE MATCH(TEXT) AGAINST('other_text')
, and there is no> 0
comparison operator.
-
Indexes in the MEMORY Storage Engine
For in-memory storage engines,
HASH
indexes are used by default, but indexes are also supportedBTREE
.
3 Column Indexes && Multiple-Column Indexes
Mysql supports a single column as an index, and can also use multiple columns as an index. When using multiple columns, use the leftmost (leftmost prefix of the index) column to query, and the index can be used, otherwise, Mysql will not be able to use the index , for example:
Suppose a table contains the following indexes:
INDEX name (last_name,first_name)
The name index can be used for the following query statements:
SELECT * FROM test WHERE last_name='Jones';
SELECT * FROM test
WHERE last_name='Jones'
AND (first_name='John' OR first_name='Jon');
SELECT * FROM test
WHERE last_name='Jones'
AND first_name >='M' AND first_name < 'N';
The following statement cannot use the index because it does not use the leftmost column for the query:
SELECT * FROM test WHERE first_name='John';
SELECT * FROM test
WHERE last_name='Jones' OR first_name='John';
Assuming there are two columns col1
and col2
, if the index is just built on col1
and col2
, then the index can be used directly, but if col1
the col2
sum is a separate index (that is, not a multi-column index), then Mysql will try to use Index Merge optimization
(see Section 8.2.1.3, "Index Merge Optimization" ) technology, or the condition for judging which of the two indexes is the most stringent, can exclude as many rows as possible before deciding which index to use.
4 Comparison of B-Tree and Hash Indexes
-
B-Tree Index Characteristics
The B-tree index supports = , > , >= , < , <= , or BETWEEN operators, and also supports
LIKE
operators, but it must be ensured thatLIKE
the field does not start with a wildcard.If an index does not cover all
AND
, then Mysql will not be able to use the index. In other words, in order to be able to use the index, it must be ensured that the prefix (the leftmost part) of an index appears in eachAND
, for example as follows:... WHERE index_part1=1 AND index_part2=2 AND other_column=3 /* index = 1 OR index = 2 */ ... WHERE index=1 OR A=10 AND index=2 /* optimized like "index_part1='hello'" */ ... WHERE index_part1='hello' AND index_part3=5 /* Can use index on index1 but not on index2 or index3 */ ... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
The following statements will not use indexes:
/* index_part1 is not used */ ... WHERE index_part2=1 AND index_part3=2 /* Index is not used in both parts of the WHERE clause */ ... WHERE index=1 OR A=10 /* No index spans all rows */ ... WHERE index_part1=1 OR index_part2=10
(Don't understand well here?)
have to be aware of is:
Mysql does not choose to use the index at any time. Sometimes, when a large number of rows need to be read, the efficiency of using the index may be lower than the efficiency of the index,
table scan
because the index will cause more seek consumption on the disk, and thetable scan
Due to continuous reading, disk I/O can be used more efficiently -
Hash Index Characteristics
Hash
Compared withB
the tree index, the index may have the following differences:Hash
Indexes can only be used for the=
OR<=>
operator, not for range queries- The optimizer cannot use
Hash
indexes to speed upORDER BY
operations Mysql
value
Unable to evaluate how many lines (BETWEEN
statements) are between two- Only full index will work properly, not like
BTREE
that, useleftmost prefix key
5 Use of Index Extensions
InnoDB will automatically add the primary key to the secondary index as a new index, which is done internally and cannot be perceived by the user, such as the following table:
CREATE TABLE t1 (
i1 INT NOT NULL DEFAULT 0,
i2 INT NOT NULL DEFAULT 0,
d DATE DEFAULT NULL,
PRIMARY KEY (i1, i2),
INDEX k_d (d)
) ENGINE = InnoDB;
At this time, for the index k_d, its internal real implementation method is: (d, i1, i2)
. That is, the primary key (i1, i2) is automatically added to the back of k_d to form a new secondary index.
This optimization method can be used in index access scenarios of , ref
, and , andrange
index_merge
Loose Index Scan
join
sort
MIN()/MAX()。
For example the following statement:
SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01'
At this time, since the index will be i1
added internally k_d
, this statement can use (d, i1)
such an index ( (d, i1)
it is the leftmost prefix of the index (d, i1, i2)
). Since more columns are used, the number of rows to be scanned will be greatly reduced.
6 Invisible Indexes
This kind of index refers to the index that actually exists, but the optimizer will not use it. It can only be set to non primary key
. Other types of indexes support setting to INVISIBLE
.
For example the following example:
CREATE TABLE t1 (
i INT,
j INT,
k INT,
INDEX i_idx (i) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX j_idx ON t1 (j) INVISIBLE;
ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;
The general purpose of this kind of index: to test the impact of removing an index on performance, because this kind of index is not really removed, but the optimizer no longer considers the index, so it will not have much impact on the table .
Note that although the index is Invisible
valid, this index has the same complete functions as the ordinary index. That is to say, Mysql will also update when adding, deleting, and modifying. Similarly Invisible Index
, if it is created on a very large table Invisible Index
, it will be the same as the ordinary index. , the cost is also very huge.
7 Descending Indexes
Mysql supports descending indexes. Unlike previous versions, the DESC in the index definition is no longer ignored, and the internal storage method of the index is also adopted in descending order; before that, Mysql used the method of scanning the index in reverse order. Currently The efficiency of descending order is much higher than before.
The use of descending indexes is mainly for the following scenarios:
- Descending indexes only support the InnoDB engine, and have the following limitations:
- If a secondary index has descending keys or a primary key contains descending keys, then Mysql cannot support modifying Buffering
- InnoDB's SQL parser does not use descending indexes. For full-text queries, this means that columns on tables that are already indexed
FTS_DOC_ID
cannot be defined as descending indexes.
- An index with descending keys cannot be optimized with MIN/MAX, especially for statements that contain aggregate functions without GROUP BY.
- Descending indexes only support BTREE, not HASH indexes, and descending indexes cannot support FULLTEXT or SPATIAL indexes