SQL ability practice of deep love

Posted by markmil2002 on Thu, 17 Feb 2022 12:54:18 +0100

@SQL skill improvement

MySQL index

At present, I'm a junior. I want to be engaged in data warehouse development, but the ability of data development is also particularly high in the market,
I also interviewed many small companies and agreed that I didn't have a deeper understanding of the workflow and project expansion of the whole project
 And the problems encountered in the project.
The foundation is not particularly solid, so I hope to write a blog to record my usual practice SQL Ability improvement notes.

Welcome to criticize and correct, thank you for your browsing and clicking...
W3 school sql query dictionary

Use of index

Create index

select * from tb_item; -- 3000000 Data bar
id: primary key 
title: Without index, the query efficiency is relatively low

Create index
create index indx_tem_title on tb_item;
The underlying database is creating an index

Indexes are one of the most efficient ways to optimize queries
 Creating an index can improve query efficiency and make rational use of the index

How to avoid index invalidation

Create federated index
create index name on table(column)
create index idx_seller_name_sta_addr on tb_seller(name,status,address);

explain To analyze SQL Query efficiency of engine
1,Weight matching
select * from tb_seller where name='Xiaomi Tech ' and status='1' and address = 'Xi'an';

mysql> explain select * from tb_seller where name='Xiaomi Tech ' and status='1' and address = 'Xi'an';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref               | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 813     | const,const,const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
1 row in set (0.00 sec)

Most sitting front rule

Start with the leftmost column, and there are no skipped columns in the middle
explain select * from tb_seller where name='Xiaomi Tech ';

mysql> explain select * from tb_seller where name='Xiaomi Tech ';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

explain select * from tb_seller where name='Xiaomi Tech ' and status='1';

mysql> explain select * from tb_seller where name='Xiaomi Tech ' and status='1';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref         | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 410     | const,const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)


Query is not in name Start with status start
explain select * from tb_seller where status='1' and address = 'Xi'an';

mysql> explain select * from tb_seller where status='1' and address = 'Xi'an';
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tb_seller | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

Index order changes
explain select * from tb_seller where address = 'Xi'an' and name = 'Xiaomi Tech ' and status='1' ;

mysql> explain select * from tb_seller where address = 'Xi'an' and name = 'Xiaomi Tech ' and status='1' ;
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref               | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 813     | const,const,const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
1 row in set (0.00 sec)


The index query is the same as where The order of the conditions is irrelevant
 Leftmost column, no jumping
explain select * from tb_seller where name = 'Xiaomi Tech ' and address = 'Xi'an' ;

mysql> explain select * from tb_seller where name = 'Xiaomi Tech ' and address = 'Xi'an' ;
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

Just go name The index, similar to the operation of climbing stairs, can only be used step by step

Invalid range query

explain select * from tb_seller where name='Xiaomi Tech ' and status > '1'  and address = 'Beijing';

mysql> explain select * from tb_seller where name='Xiaomi Tech ' and status > '1'  and address = 'Beijing';
+----+-------------+-----------+-------+--------------------------+--------------------------+---------+------+------+-------------+
| id | select_type | table     | type  | possible_keys            | key                      | key_len | ref  | rows | Extra       |
+----+-------------+-----------+-------+--------------------------+--------------------------+---------+------+------+-------------+
|  1 | SIMPLE      | tb_seller | range | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 410     | NULL |    1 | Using where |
+----+-------------+-----------+-------+--------------------------+--------------------------+---------+------+------+-------------+
1 row in set (0.00 sec)

The length of the index has changed
 Just go name,status,The index of the field after the range query is invalid, status,invalid

Do not operate on the index
explain select * from tb_seller where name = 'Xiaomi Tech ';

mysql> explain select * from tb_seller where name = 'Xiaomi Tech ';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

explain select * from tb_seller where substring(name,3,2) = 'Xiaomi Tech ';

mysql> explain select * from tb_seller where substring(name,3,2) = 'Xiaomi Tech ';
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tb_seller | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using where |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.03 sec)

If calculated on the above index, the index will become invalid

No single quotation mark is added to the string, and the index is invalid
explain select * from tb_seller  where name = 'Xiaomi Tech ' and status = 1;

mysql> explain select * from tb_seller  where name = 'Xiaomi Tech ' and status = 1;
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

403 yes name Index length of

explain select * from tb_seller  where name = 'Xiaomi Tech ' and status = '1';

mysql> explain select * from tb_seller  where name = 'Xiaomi Tech ' and status = '1';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref         | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 410     | const,const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)

Detected status yes string If the field of type is not quoted, the bottom layer will be a hermit type
 If the underlying layer operates on the index, the index will become invalid

String type, with single quotation marks

Use overlay index
mysql> explain select * from tb_seller where name = 'Xiaomi Tech ';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

Extra       

mysql> explain select name,status,address from tb_seller where name = 'Xiaomi Tech ';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+--------------------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref   | rows | Extra                    |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+--------------------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 403     | const |    1 | Using where; Using index |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)

or Failure problem

explain select * from tb_seller where name = 'Xiaomi Tech ' or nickname = ''Xiaomi official flagship store;
mysql> explain select * from tb_seller where name = 'Xiaomi Tech ' or nickname = 'Xiaomi official flagship store';
+----+-------------+-----------+------+--------------------------+------+---------+------+------+-------------+
| id | select_type | table     | type | possible_keys            | key  | key_len | ref  | rows | Extra       |
+----+-------------+-----------+------+--------------------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | tb_seller | ALL  | idx_seller_name_sta_addr | NULL | NULL    | NULL |   12 | Using where |
+----+-------------+-----------+------+--------------------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

use and The index is valid. Just go name Indexes

Index failure summary

 1. Full value matching, specifying specific values for all columns in the index
 2. Leftmost prefix rule
 3. The column on the right of range query cannot use index
 4. Do not operate on the index column. The index will become invalid
 5. The string is not enclosed in single quotation marks, resulting in index invalidation
 6. Try to use overlay indexes and avoid them select * ,Use overlay indexes whenever possible
 Queries that only access indexes (index columns, full query columns), reduce select * 
 Commonly used query columns can be added to a composite index, otherwise they will be used confition where Will use back to table query
 7. or If the index fails, it will be effective only if there is an index
 8. like Fuzzy matching problem,%If the number is added to the front, it will become invalid
 Use overlay index to solve this problem. The query includes primary key index, simple index and composite index
 explain select sellerid,name,status,address from tb_seller where name like '%science and technology%';
 explain select sellerid,name,status,address,password from tb_seller where name like '%science and technology%';
 The second one is to overwrite the index without going through the index. The query only includes the index

Extra

1. using index: It will appear when using overlay index
2. using where: When the index is used for searching, you need to go back to the table to query the required data
3. using index condition: The index is used in the search, but the data needs to be queried back to the table
4. using index & using where :  The search uses the index, but the required data can be found in the index column. The index does not need to query the data back to the table

Pay attention to MySQL performance

1. The problem that full table scanning is faster than indexing
2.  If the full table scan is fast, the index will not be used, is null The index takes effect, is not null Index failure
	is null or is not null ,First, I will judge the fast problem of full table and index
	It is related to the amount of data. The small one is indexed
3. in and not in
	in Go to the index, not in No index
mysql> explain select * from tb_seller where sellerid in ("oppo","xiaomi","sina");
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table     | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | tb_seller | range | PRIMARY       | PRIMARY | 402     | NULL |    3 | Using where |
+----+-------------+-----------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)

Single column index and composite index

Try to use composite index and less single column index. Composite index is equivalent to creating multiple indexes
 If a single column index is used, when multiple fields are queried, only the best index will be used.
mysql> show index from tb_seller;
+-----------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name                 | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb_seller |          0 | PRIMARY                  |            1 | sellerid    | A         |          12 |     NULL | NULL   |      | BTREE      |         |               |
| tb_seller |          1 | idx_seller_name_sta_addr |            1 | name        | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| tb_seller |          1 | idx_seller_name_sta_addr |            2 | status      | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| tb_seller |          1 | idx_seller_name_sta_addr |            3 | address     | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| tb_seller |          1 | index_tb_seller_address  |            1 | address     | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
+-----------+------------+--------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
5 rows in set (0.00 sec)

mysql> drop index index_tb_seller_address on tb_seller;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

explain select * from tb_seller where name = 'Xiaomi Tech ' and status = '0' and address = 'Xi'an';

mysql> explain select * from tb_seller where name = 'Xiaomi Tech ' and status = '0' and address = 'Xi'an';
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
| id | select_type | table     | type | possible_keys            | key                      | key_len | ref               | rows | Extra       |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name_sta_addr | idx_seller_name_sta_addr | 813     | const,const,const |    1 | Using where |
+----+-------------+-----------+------+--------------------------+--------------------------+---------+-------------------+------+-------------+
1 row in set (0.00 sec)

Delete composite index

mysql> drop index idx_seller_name_sta_addr on tb_seller;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

Create three single column indexes
create index idx_seller_name on tb_seller(name);
create index idx_seller_status on tb_seller(status);
create index idx_seller_address on tb_seller(address);

mysql> show index from tb_seller;
+-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table     | Non_unique | Key_name           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb_seller |          0 | PRIMARY            |            1 | sellerid    | A         |          12 |     NULL | NULL   |      | BTREE      |         |               |
| tb_seller |          1 | idx_seller_name    |            1 | name        | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| tb_seller |          1 | idx_seller_status  |            1 | status      | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| tb_seller |          1 | idx_seller_address |            1 | address     | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
+-----------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
4 rows in set (0.00 sec)

This only takes name This index, name Indexes are optimal, rather than using all indexes
 It mainly depends on whether the recognition degree is the highest. For single column index combined query, it is easiest to use that index
mysql> explain select * from tb_seller where name = 'Xiaomi Tech ' and status = '0' and address = 'Xi'an';
+----+-------------+-----------+------+------------------------------------------------------+-----------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys                                        | key             | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+------------------------------------------------------+-----------------+---------+-------+------+-------------+
|  1 | SIMPLE      | tb_seller | ref  | idx_seller_name,idx_seller_status,idx_seller_address | idx_seller_name | 403     | const |    1 | Using where |
+----+-------------+-----------+------+------------------------------------------------------+-----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

View index usage

Index usage for the current session
mysql> show status like "Handler_read%";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 0     |
| Handler_read_key      | 23    |
| Handler_read_last     | 0     |
| Handler_read_next     | 0     |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 16    |
+-----------------------+-------+
7 rows in set (0.01 sec)


View global index usage
mysql> show  global status  like "Handler_read%";
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Handler_read_first    | 3     |
| Handler_read_key      | 42    |
| Handler_read_last     | 0     |
| Handler_read_next     | 1     |
| Handler_read_prev     | 0     |
| Handler_read_rnd      | 0     |
| Handler_read_rnd_next | 48    |
+-----------------------+-------+
7 rows in set (0.00 sec)

Introduction to SQL index indicators

Handler_read_first  ---->   The number of times the first entry in the index is read. If it is higher, it is marked
 The server is performing a large number of full table index scans (the lower the value, the better)

Handler_read_key  ---->  If the index is working, this value represents a row being retrieved
 The number of times the index value is read. If the value is lower, it indicates that the performance improvement of the index is not high, because the index is not often used
 The higher the value, the better

Handler_read_next  ---->  according to key The number of requests to read the next line in sequence, if you use
 This value is incremented by a range constraint or if an index scan is performed to query index columns

Handler_read_prev  ---->  The number of requests to read the previous line in key order
 Mainly used for optimization order by ... desc

Handler_read_rnd  ---->  The number of requests to read a line according to a fixed position, if you are executing
 A large number of queries and the results need to be sorted. This value is high, and you may have used a large number of queries MySQL Scan entire
 The table query or your connection does not use the key correctly. This value is high, which means that the operation efficiency is low and should be established
 Index to remedy

Handler_read_rnd_next  ---->  The number of requests to read the next line in the data file, if you
 A large number of table scans are in progress. A high value usually indicates that your table index is incorrect or the written query is not valid
 Use index

dba

Insert data for optimization

Bulk insert data

Table creation

CREATE TABLE `tb_user_2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`password` varchar(96) NOT NULL,
`name` varchar(45) NOT NULL,
`birthday` datetime DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`phone` varchar(45) DEFAULT NULL,
`qq` varchar(32) DEFAULT NULL,
`status` varchar(32) NOT NULL COMMENT 'User status',
`create_time` datetime NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_user_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;

View import effect

-- Import ordered data
mysql> load data local infile 'E:\\bigdata\\highSkill\\sql1.log' into table tb_user_1 fields terminated by ',' lines terminated by '\n';
Query OK, 1000000 rows affected, 65535 warnings (31.28 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 4000000

-- Import unordered data
mysql> load data local infile 'E:\\bigdata\\highSkill\\sql2.log' into table tb_user_2 fields terminated by ',' lines terminated by '\n';
Query OK, 1000000 rows affected, 65535 warnings (1 min 4.69 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 4000000

Summary: before inserting data in batch, make the data orderly, which can provide insertion efficiency

Turn off uniqueness check

set unique_checks=0; -- close
set unqiue_checks=1; -- open

Manually commit transactions

set autocommit=0; -- Turn off auto submit
set autocommit=1; -- Turn on auto submit

Optimize insert statement

Insert multiple pieces of data at one time

insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');

Manually commit transactions

start transaction;
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
commit;

Primary key sequential insertion

insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
insert into tb_test values(4,'Tim');
insert into tb_test values(5,'Rose');

Order by optimization

Create table structure

CREATE TABLE `emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` int(3) NOT NULL,
`salary` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

insert into `emp` (`id`, `name`, `age`, `salary`) values('1','Tom','25','2300');
insert into `emp` (`id`, `name`, `age`, `salary`) values('2','Jerry','30','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('3','Luci','25','2800');
insert into `emp` (`id`, `name`, `age`, `salary`) values('4','Jay','36','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('5','Tom2','21','2200');
insert into `emp` (`id`, `name`, `age`, `salary`) values('6','Jerry2','31','3300');
insert into `emp` (`id`, `name`, `age`, `salary`) values('7','Luci2','26','2700');
insert into `emp` (`id`, `name`, `age`, `salary`) values('8','Jay2','33','3500');
insert into `emp` (`id`, `name`, `age`, `salary`) values('9','Tom3','23','2400');
insert into `emp` (`id`, `name`, `age`, `salary`)
values('10','Jerry3','32','3100');
insert into `emp` (`id`, `name`, `age`, `salary`) values('11','Luci3','26','2900');
insert into `emp` (`id`, `name`, `age`, `salary`) values('12','Jay3','37','4500');

create index idx_emp_age_salary on emp(age,salary);

View index

mysql> show index from emp;
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| emp   |          0 | PRIMARY            |            1 | id          | A         |           2 |     NULL | NULL   |      | BTREE      |         |               |
| emp   |          1 | idx_emp_age_salary |            1 | age         | A         |          12 |     NULL | NULL   |      | BTREE      |         |               |
| emp   |          1 | idx_emp_age_salary |            2 | salary      | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

Two sorting methods of mysql

filesort sort

mysql> explain select * from emp order by age;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

According to age,salary

mysql> explain select * from emp order by age,salary;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)

Summary: sorting through multi field, single field, index and composite index is based on fileSort, which is very inefficient

using index

mysql> explain select id from emp order by age;
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key                | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
|  1 | SIMPLE      | emp   | index | NULL          | idx_emp_age_salary | 9       | NULL |   12 | Using index |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
1 row in set (0.00 sec)


mysql> explain select id ,age,salary from emp order by age;
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key                | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
|  1 | SIMPLE      | emp   | index | NULL          | idx_emp_age_salary | 9       | NULL |   12 | Using index |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
1 row in set (0.00 sec)


mysql> explain select id ,age,salary from emp order by age,salary;
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key                | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
|  1 | SIMPLE      | emp   | index | NULL          | idx_emp_age_salary | 9       | NULL |   12 | Using index |
+----+-------------+-------+-------+---------------+--------------------+---------+------+------+-------------+
1 row in set (0.00 sec)

Summary: when sorting, either all are in ascending order or all are in descending order, so the efficiency should be higher
If you sort by multiple fields, the sorting order should be consistent with the index order. Try to use the using index for sorting

In the development process, the emergence of fileSort cannot be avoided. How to optimize fileSort

fileSort optimization
1) Twice scanning algorithm, on MySQL4 1. Before sorting with this algorithm, first take out the sorting field and row pointer according to the conditions, and then sort in the sort buffer. If the sort buffer is not enough, store the sorting results in the temporary table in the temporary table. After sorting, read the records back to the table according to the row pointer. This operation may lead to a large number of random I/O operations

2) One scan algorithm: take out all the fields that meet the conditions at one time, and then sort them in the sort buffer, and then directly output the result set. The memory overhead is large during sorting, but the sorting efficiency is higher than that of the two scan algorithm.

MySQL compares the variable max_ length_ for_ sort_ The size of data and the total size of the fields taken out by the Query statement to determine whether it is the sort algorithm. If Max_ length_ for_ sort_ If the data is larger, use the one-time scanning algorithm, otherwise use the two-time scanning algorithm.

Sort can be improved appropriately_ buffer_ Size and max_length_for_sort_data system variable to increase the size of the sorting area and improve the efficiency of sorting.

mysql> show variables like 'max_length_for_sort_data';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| max_length_for_sort_data | 1024  |
+--------------------------+-------+
1 row in set (0.00 sec)


mysql> show variables like 'sort_buffer_size';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| sort_buffer_size | 262144 |
+------------------+--------+
1 row in set (0.00 sec)

Optimization of group by statement

Since group by actually performs sorting operations, and compared with order by, group by mainly performs grouping operations after sorting. Of course, if other aggregation functions are used during grouping, some aggregation function calculation is also required. Therefore, in the implementation process of group by, the index can also be used like order by
If the query includes group by but the user wants to avoid the consumption of sorting results, you can execute order by Null to prohibit sorting.

mysql> explain select age,count(*) from emp group by age;
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
1 row in set (0.00 sec)
mysql> explain select age,count(*) from emp group by age;
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
1 row in set (0.00 sec)

mysql> explain select age,count(*) from emp group by age order by null;
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra           |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
|  1 | SIMPLE      | emp   | ALL  | NULL          | NULL | NULL    | NULL |   12 | Using temporary |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------+
1 row in set (0.00 sec)

The temporary table is used, and the index is used for query

mysql> create index inde_emp_age_salary on emp(age,salary);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select age,count(*) from emp group by age order by null;
+----+-------------+-------+-------+---------------+---------------------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key                 | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------------------+---------+------+------+-------------+
|  1 | SIMPLE      | emp   | index | NULL          | inde_emp_age_salary | 9       | NULL |   12 | Using index |
+----+-------------+-------+-------+---------------+---------------------+---------+------+------+-------------+
1 row in set (0.00 sec)

Subquery optimization

Finite or condition

To prevent index invalidation, composite indexes cannot be used, and single column indexes must be used
Use union to replace or, and the type is range

Paging condition query

Application optimization

Database connection pool

Reduce access to MySQL

  • One time read
  • Add cache layers redis, Memcache, mybatis and hibernate

load balancing

  • Use MySQL replication to complete streaming query (master-slave replication, read-write separation)
  • Using distributed database architecture

Query cache optimization of MySQL

Cache parameter configuration

SHOW VARIABLES LIKE 'have_query_cache';
SHOW VARIABLES LIKE 'query_cache_type'; 
SHOW VARIABLES LIKE 'query_cache_size';
SHOW STATUS LIKE 'Qcache%';

SQL exercise record

Use of windowing function

SQL JOIN

join nameDifference description
JoinIf there is a match in the table, the row is returned
Left JoinEven if there is no match in the right table, all rows are returned from the left table
RightEven if there is no match in the left table, all rows are returned from the right table
full joinAs long as there is a match in one of the tables, the row is returned

Sort window
Sort function row_number,rank,dense_ The difference between rank

Sort nameDifference description
row_numberThere is no juxtaposition
dense_rank & rankIf there is juxtaposition, rank will jump sort
row_numberRegardless of juxtaposition, even if the order is the same, the order is a natural number of continuity
dense_rank & rankConsidering the situation of juxtaposition, the difference is that rank is very jumping. The number of juxtaposed sorting will affect the next ranking, which is represented by the interruption of numbers, while deny_ Rank is continuous no matter how many are arranged side by side

sort

1. In the employees table, output first_ Name ranking (sorted in ascending order by first_name) is the first of odd ranking_ name.

Problem solving ideas:
	View table structure
		emp_no|int|NO|PRI|None|
		birth_date|date|NO||None|
		first_name|varchar(14)|NO||None|
		last_name|varchar(16)|NO||None|
		gender|char(1)|NO||None|
		hire_date|date|NO||None|
	yes first_name Sort and output first_name,rank
		select first_name,row_number() over(order by first_name asc) as r_num from employees;
	Modify the original table join operation
		select e.first_name
		from employees e join
		(
			select first_name,row_number() over(order by first_name asc) as r_num
			from employees
		) t
		on e.first_name = t.first_name
		where t.r_num % 2 = 1;

dense_rank()

2. Passing according to the number of questions_ In the number table, the ranking of the passed questions is the same, in ascending order

Analytical ideas:
	The first is sorting. I just want to use it rank(),row_number(),dense_rank()Window function to realize the sorting process
	Because it is a continuous and uninterrupted operation, parallel operation must be considered. Therefore, this time, it is used dense_rank()

SQL to write:
	select id,number,dense_rank() over(order by number desc) as t_rank
	from passing_number;	

Whether in the process of interview or in the realization of requirements, sorting and windowing are often used by us. Generally, we use rank_number() and deny_ There are many rank() functions...

Topics: MySQL Big Data hive