MySQL index optimization rules

index

Introduction

Index (also called "key" in MySQL) is a data structure for the storage engine to quickly find records-"High Performance MySQL"

The index is created based on a column in the data table, and the index is the data structure

Since it is a data structure, which data structure does the index use?

Insert picture description here

The first type: BTREE
  1. BTREE has good time efficiency, and its time complexity in search, delete, and insert operations is all logarithmic, that is, O(logn).

  2. The data stored on the B-tree is ordered. Usually the data structure used when creating an index is determined by the database, but some databases can specify which data structure to use to create an index.

The second type: HASH
  1. The query efficiency of the Hash table is very high, especially for queries that compare strings for equality.
  2. The principle of Hash index is that the column value is used as the key of the hash table, and the pointer of the row is stored in the value.
  3. Hash table is an unordered data structure, and in many cases it cannot improve efficiency.
How does index improve query efficiency?

An index is essentially a data structure that stores column values. If a BTREE index is used on a column, then these column values ​​are sorted in the index, and the ordered value is the main reason why the index can improve query performance.

What is stored in the index?

A pointer to the position of the associated row in the table is stored in the index. That is to say, in addition to saving the column value, the index also saves the position information of the row associated with the column value in the table.

Index category

Ordinary index: only speed up queries

Unique index: accelerated query + unique column value (null is possible)

Primary key index: accelerated query + unique column value (no null) + only one in the table

Combined index: multiple column values ​​form an index, dedicated to combined search, and its efficiency is greater than index merging

Full-text index: segment the content of the text and search

Design Principles

1) The column suitable for indexing is the column that appears in the where clause, or the column specified in the join clause;

2) For classes with a small cardinality, the indexing effect is poor, and there is no need to create an index in this column;

3) Use a short index. If you index a long string column, you should specify a prefix length, which can save a lot of index space;

4) Don't over-index. Indexing requires additional disk space and reduces the performance of write operations. When the table content is modified, the index will be updated or even reconstructed. The more index columns, the longer this time will be. So only maintain the required index to facilitate the query.

Basic understanding
查看索引:show index from user
基数:单个列唯一键(distict_keys)的数量叫做基数。
回表: 数据库根据索引找到了指定的记录所在行后,还需要根据rowid再次到数据块里取数据的操作。

SQL preparation

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `age` int(10) NOT NULL DEFAULT 0,
  `gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '0:男 1:女',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `level` int(10) NOT NULL DEFAULT 0,
  `create_time` datetime NOT NULL DEFAULT '2000-01-01 00:00:00',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `idx_name_age_gender`(`name`, `age`, `gender`) USING BTREE COMMENT '组合索引'
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    

INSERT INTO `user` VALUES (1, 'zhangsan', 20, 0, '[email protected]', 1, '2000-01-01 00:00:00', '2020-05-06 13:47:29');
INSERT INTO `user` VALUES (2, 'lisi', 10, 1, '[email protected]', 2, '2000-01-01 00:00:00', '2020-05-06 13:47:32');
INSERT INTO `user` VALUES (3, 'wangwu', 30, 0, '[email protected]', 3, '2000-01-01 00:00:00', '2020-05-06 13:47:35');

1. Combined index full value matching

Use a joint index for a field
explain select * from user where name = 'zhangsan';

Use a joint index for a field
The explain analysis, the type is ref, the index is used, and the efficiency is high. key_len is 62. According to the key_len calculation rules, if the field type is varchar(n) and is in utf-8 encoding format, then key_len=3n+2, and name is used after where, then key_len=3*20+2=62, Prove that the index uses the
first field name of the joint index , and you can also see a const from the ref.

Use joint index two fields
explain select * from user where name = 'zhangsan' and age = 20

Use joint index two fields

Three fields using joint index
explain select * from user where name = 'zhangsan' and age = 20 and gender = 0;

Three fields using joint index

2. The best left prefix rule

If it is a composite index, you must follow the leftmost prefix rule (the conditions after where need to start from the leftmost front column of the index and do not skip the columns in the index)

(有效索引):explain select * from user where name = 'zhangsan' and age = 20 and gender = 0;
(无效索引):explain select * from user where age = 20 and gender = 0;

注:最左法则指的是我们建的组合索引最左面字段要出现在查询条件中

3. Avoid operations on index columns

Calculations, use of functions, and automatic or manual type conversion on index columns will cause the index to fail, and the query will turn to a full table scan.

(索引有效)explain select * from user where name = 'zhangsan'
(索引失效)explain select * from user where left(name,5) = 'zhang'

4. The index column on the right side of the storage engine range condition is invalid

explain select * from user where name = 'zhangsan' and age = 20 and gender = 0;
(三个字段都使用“=”号,都使用了索引)
explain select * from user where name = 'zhangsan' and age  > 20 and gender = 0;
(索引未完全使用,在满足age为“=”号条件时全部索引使用,否则,范围之后的索引失效。)

5. Try to use a covering index for queries that only access the index

explain select name,age from user where name = 'zhangsan' and age = 20 and gender = 0;

Covering index
When an index is used in the query, the * that covers the query with the index column is called a covering index.

6. Avoid the use of (!= or <>, is null, is not null)

explain select name,age from user where name != 'zhangsan'

Insert picture description here
Extra shows Using whre Using index, indicating that the query column is covered by the index column, but the condition after where does not use the index, which means that the data that meets the conditions cannot be directly searched through the index.

7. (like'%aaa') index failure full table scan

8. The indexed column is not allowed to be null

  • Single-column indexes do not store null values, and composite indexes do not store all-null values. If the column is allowed to be null, you may get "unexpected" result sets. Therefore, please use the not null constraint and the default value.
  • IS NULL can hit the index, IS NOT NULL cannot hit the index

9. Range condition query can hit the index

1.范围条件有:<、<=、>、>=、between等
2.范围列可以用到索引(联合索引必须是最左前缀),但是范围列后面的列无法用到索引,索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引
3.如果是范围查询和等值查询同时存在,优先匹配等值查询列的索引

Use the EXPLAIN command to analyze the SQL query statements you write yourself, and be a programmer who pursues SQL performance, hehehe...

If you have any questions or different opinions, please leave a message and exchange together. The blogger will reply as soon as he sees it...

Insert picture description here

Guess you like

Origin blog.csdn.net/mrhs_dhls/article/details/105949192