MySQL Advanced - storage engine + stored procedure + index (detailed 01)

Table of contents

1. mysql architecture 

2. Storage engine

2.1. Storage Engine Overview

2.2.1.InnoDB

2.2.2.MyISAM CODE

2.2.3. Storage engine selection

3. Stored procedures

3.1. Overview of stored procedures and functions 

3.2. Create a stored procedure

3.3. Call stored procedure

3.4. View stored procedures

3.5. Delete stored procedure

3.6. Grammar

3.6.1. Variables

3.6.2.if condition judgment

3.6.3. Passing parameters

3.6.4. case structure

3.6.5. while loop

3.6.6.repeat structure

3.6.7. Cursor/Cursor

3.7. Stored function---stored procedure function: the function has a return value

4. Index

4.1. Index overview

4.2. Index advantages and disadvantages

4.3. Index structure

4.3.1. Binary tree

4.3.2. B-TREE structure

4.3.3.B+Tree structure-->Mysql

4.3.4. The structure of B+tree in the database

4.4. Index classification

4.5. Index syntax 

4.6. Performance analysis

4.7. Index usage rules


1. mysql architecture 

1) Connection layer

It mainly completes some similar connection processing, authorization authentication, and related security solutions. On this layer , the concept of thread pool is introduced to provide threads for clients that pass authentication and secure access. SSL-based secure links can also be implemented on this layer. The server also verifies the operating authority it has for each client that accesses securely.

2) Service layer

The second-tier architecture mainly completes most of the core service functions, such as SQL interface, cached query, SQL analysis and optimization, and execution of some built-in functions. All cross-storage engine functions are also implemented at this layer, such as procedures and functions. At this layer, the server will parse the query and create a corresponding internal parsing tree, and optimize it accordingly, such as determining the order of table queries, whether to use indexes, etc., and finally generate corresponding execution operations. If it is a select statement, the server will also query the internal cache. If the cache space is large enough, this can greatly improve the system performance in an environment that solves a large number of read operations.

3) Engine layer [storage engine]

The storage engine layer, the storage engine is really responsible for the storage and retrieval of data in MySQL, and the server communicates with the storage engine through the API. Different storage engines have different functions, so we can choose the appropriate storage engine according to our needs. Before [MyISAM]: After MySQL5.5, the default storage engine of MySQL is InnoDB, and the index structure used by InnoDB by default is B+ tree. The above service layer interacts with the storage engine layer through the API interface.

4) Storage layer

The data storage layer mainly stores data on the file system and completes the interaction with the storage engine.

Compared with other databases, MySQL is a bit different in that its architecture can be applied and function well in many different scenarios. It is mainly reflected in the storage engine. The plug-in storage engine architecture separates query processing from other system tasks and data storage and extraction. This architecture can select an appropriate storage engine according to business needs and actual needs.

2. Storage engine

2.1. Storage Engine Overview

Different from most databases, MySQL has a concept of storage engine, and the optimal storage engine can be selected for different storage requirements .

The storage engine is the implementation of technologies such as storing data, building indexes, and updating query data. Storage engines are table-based , not library-based.

Databases such as Oracle and SqlServer have only one storage engine. MySQL provides a plug-in storage engine architecture. Therefore, MySQL has a variety of storage engines, and you can use the corresponding engine as needed.

You can query the storage engines supported by the current database by specifying show engines:\

If you do not specify a storage engine when creating a new table, the system will use the default storage engine. The default storage engine before MySQL 5.5 was MyISAM, and it was changed to InnoDB after 5.5.

View the default storage engine of Mysql database, command:

 show variables like '%storage_engine%' ; 

2.2.1.InnoDB

InnoDB storage engine is the default storage engine of Mysql. The InnoDB storage engine provides transaction safety with commit, rollback, and crash recovery capabilities. However, compared with the MyISAM storage engine, InnoDB writes are less efficient and will take up more disk space to retain data and indexes.

The InnoDB storage engine is different from other storage engines:

transaction control

-- 创建表
create table goods_innodb(
	id int NOT NULL AUTO_INCREMENT,
	name varchar(20) NOT NULL,
    primary key(id)
)ENGINE=innodb DEFAULT CHARSET=utf8;

-- innodb支持事务 

start transaction; -- 开启事务
INSERT INTO goods_innodb VALUES (1,'aaa'); -- 添加数据
commit; -- 提交事务  因为支持事务所以不提交则添加失败

Test and find that there are transactions in InnoDB


foreign key constraints

The only storage engine that supports foreign keys in MySQL is InnoDB . When creating a foreign key, the parent table must have a corresponding index. When the child table creates a foreign key, the corresponding index will be automatically created.

In the following two tables, country_innodb is the parent table, country_id is the primary key index, city_innodb is the child table, and the country_id field is the foreign key, corresponding to the primary key country_id of the country_innodb table.

-- 创建表 测试是否支持外键
create table country_innodb(
	country_id int NOT NULL AUTO_INCREMENT,
    country_name varchar(100) NOT NULL,
    primary key(country_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

create table city_innodb(
	city_id int NOT NULL AUTO_INCREMENT,
    city_name varchar(50) NOT NULL,
    country_id int NOT NULL, -- 外键  
    primary key(city_id),
    key idx_fk_country_id(country_id),
    CONSTRAINT `fk_city_country` FOREIGN KEY(country_id) REFERENCES country_innodb(country_id) ON DELETE RESTRICT ON UPDATE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into country_innodb values(null,'China'),(null,'America'),(null,'Japan');
insert into city_innodb values(null,'Xian',1),(null,'NewYork',2),(null,'BeiJing',1);

When creating an index, you can specify the corresponding operations on the child table when deleting or updating the parent table, including RESTRICT, CASCADE, SET NULL, and NO ACTION.

  • RESTRICT is the same as NO ACTION, which means that the parent table cannot be updated when the child table has associated records;
  • CASCADE indicates that when the parent table is updated or deleted, the records corresponding to the child table are updated or deleted;
  • SET NULL means that when the parent table is updated or deleted, the corresponding field of the child table is SET NULL.

For the two tables created above, the foreign key specification of the child table is ON DELETE RESTRICT ON UPDATE CASCADE, so when the main table deletes records, if the child table has corresponding records, it is not allowed to delete, and the main table is updating records When , if the sub-table has a corresponding record, the sub-table is correspondingly updated.

The data in the table is shown in the figure below:

Delete the country data whose country_id is 1:

 delete from country_innodb where country_id = 1;

There is a foreign key constraint, the deletion fails

 Update the field country_id of the main table country table:

update country_innodb set country_id = 100 where country_id = 1;

After updating, the data information of the subtable is:


2.2.2.MyISAM CODE

MyISAM does not support transactions, nor does it support foreign keys. Its advantage is that the access speed is fast, there is no requirement for the integrity of the transaction, or the SELECT and INSERT-based applications can basically use this engine to create tables. There are two important features:

does not support transactions

-- 创建表
create table goods_myisam(
	id int NOT NULL AUTO_INCREMENT,
	name varchar(20) NOT NULL,
    primary key(id)
)ENGINE=myisam DEFAULT CHARSET=utf8;
-- MyISAM不支持事务
start transaction; -- 开启事务
insert into goods_MyISAM VALUES (1,'aaa'); -- 添加数据 

Through testing, we found that there is no transaction control in the MyISAM storage engine;

foreign keys are not supported

create table country_myisam(
	country_id int NOT NULL AUTO_INCREMENT,
    country_name varchar(100) NOT NULL,
    primary key(country_id)
)ENGINE=MyISAM DEFAULT CHARSET=utf8;


create table city_myisam(
	city_id int NOT NULL AUTO_INCREMENT,
    city_name varchar(50) NOT NULL,
    country_id int NOT NULL,
    primary key(city_id),
    key idx_fk_country_id(country_id),
    CONSTRAINT `fk_city_country` FOREIGN KEY(country_id) REFERENCES country_myisam(country_id) ON DELETE RESTRICT ON UPDATE CASCADE
)ENGINE=MyISAM DEFAULT CHARSET=utf8;



insert into country_myisam values(null,'China'),(null,'America'),(null,'Japan');
insert into city_myisam values(null,'Xian',1),(null,'NewYork',2),(null,'BeiJing',1);

 Through the deletion test, we found that in the MyISAM storage engine, there is no foreign key constraint

  • innodb: supports transactions and foreign keys, and the table structure exists in a file, and the index and data are stored in the idb file
  • myisam: does not support transactions and foreign keys, its table structure exists in frm, indexes and data exist in myi and myd files respectively

2.2.3. Storage engine selection


When selecting a storage engine, an appropriate storage engine should be selected according to the characteristics of the application system. For complex application systems, multiple storage engines can also be selected for combination according to the actual situation.

  • InnoDB: It is the default storage engine of Mysql , which supports transactions and foreign keys. If the application has relatively high requirements on the integrity of the transaction, requires data consistency under concurrent conditions, and data operations include many update and delete operations in addition to insert and query, then the InnoDB storage engine is a more suitable choice .
  • MyISAM: If the application is mainly read and insert operations, with only a few update and delete operations, and the requirements for transaction integrity and concurrency are not very high, then this storage engine is very suitable to choose.

3. Stored procedures

3.1. Overview of stored procedures and functions 

Stored procedures and functions are a collection of SQL statements that have been compiled and stored in the database in advance . Calling stored procedures and functions can simplify a lot of work for application developers, reduce data transmission between the database and application servers , and improve data processing. Efficiency is beneficial.

The difference between a stored procedure and a function is that a function must have a return value, while a stored procedure does not.

Function: is a procedure that returns a value;

Procedure: is a function that does not return a value;


3.2. Create a stored procedure

grammar:

CREATE PROCEDURE procedure_name ([proc_parameter[,...]]) 
begin
	-- SQL语句
end ;

Example:

-- 存储过程入门01
delimiter $  -- 定义结束符
CREATE PROCEDURE p01()
BEGIN
   select 'Hello 存储过程' ;
END $

delimiter ;

DELIMITER : This keyword is used to declare the delimiter of the SQL statement, telling the MySQL interpreter whether the command in this segment has ended and whether mysql can be executed. By default, the delimiter is a semicolon;. In the command line client, if a line of command ends with a semicolon, mysql will execute the command after pressing Enter.

3.3. Call stored procedure

CALL p01();

3.4. View stored procedures


-- 查询mysqlg数据库中的所有的存储过程
select name from mysql.proc where db='mysqlg';

-- 查询存储过程的状态信息
show procedure status;

3.5. Delete stored procedure

DROP PROCEDURE p01

3.6. Grammar

Stored procedures are programmable, which means that variables, expressions, and control structures can be used to complete more complex functions.

3.6.1. Variables

DECLARE:

A local variable can be defined through DECLARE, and the scope of the variable can only be in the BEGIN...END block.

DECLARE var_name[,...] type [DEFAULT value]

Example :

-- 声明变量
delimiter $
create procedure p02()  -- 创建存储过程
 begin 
 declare num int default 5; -- 声明num,默认为5
 	select num+ 10;  -- 输出加10
 end $
 delimiter ; 
 
CALL p02(); -- 调用存储过程

SET: Use SET for direct assignment, and you can assign constants or expressions. The specific syntax is as follows:

  SET var_name = expr [, var_name = expr] ...

Example :

-- 为变量重新赋值
DELIMITER $
CREATE  PROCEDURE p03()
  BEGIN
  	declare num int default 5; -- 设置变量nun默认为5
  	SET num = 20;  -- 重新赋值num为20
  	SELECT num ;  -- 输出
  END$
DELIMITER ;
CALL p03(); -- 调用存储过程

You can also perform assignment operations through select ... into:

-- 通过select ... into 方式进行赋值操作 :
DELIMITER $
CREATE  PROCEDURE p04()
BEGIN
    declare num int default 5;    -- num默认为5
	  select count(*) into num from city_innodb; -- 将表city_innodb中共几条数据赋值给num
	  select num;  -- 输出
END$
DELIMITER ; 

CALL p04(); -- 调用存储过程

3.6.2.if condition judgment

Grammatical structures :

if search_condition then statement_list

	[elseif search_condition then statement_list] ...
	
	[else statement_list]
	
end if;

need:

根据定义的身高变量,判定当前身高的所属的身材类型 并输出该身材
	180 及以上 ----------> 身材高挑

	170 - 180  ---------> 标准身材

	170 以下  ----------> 一般身材

Example :

delimiter $

create procedure p05()
begin
  declare  height  int  default  175; 
  declare  description  varchar(50);
  if  height >= 180  then
    set description = '身材高挑';
  elseif height >= 170 and height < 180  then
    set description = '标准身材';
  else
    set description = '一般身材';
  end if;
  
  select description ;
end$

delimiter ;

call p05();

3.6.3. Passing parameters

Grammar format:

create procedure procedure_name([in/out/inout] 参数名   参数类型)
...


IN :   该参数可以作为输入,也就是需要调用方传入值 , 默认
OUT:   该参数作为输出,也就是该参数可以作为返回值
INOUT: 既可以作为输入参数,也可以作为输出参数

IN - input

Requirement: According to the defined height variable, determine the body type of the current height 

Example :

delimiter $

create procedure p06(in height int)
begin
    declare description varchar(50) default '';
  if height >= 180 then
    set description='身材高挑';
  elseif height >= 170 and height < 180 then
    set description='标准身材';
  else
    set description='一般身材';
  end if;
  select concat('身高 ', height , '对应的身材类型为:',description);
end$

delimiter ;

call p06(200);

OUT - output

Requirement: Get the body type of the current height according to the incoming height variable

Example:

delimiter $
CREATE PROCEDURE p07(in height int ,out description VARCHAR(50))
BEGIN  
 if height >= 180 then 
    set description = '111' ;
 ELSEIF height >= 170 and height < 180 THEN
	set description = '222' ; 
 ELSE
   set description = '333' ; 
 END if ;
end $
delimiter ;

 transfer:

CALL p07(180,@a); -- @代表定义一个局部变量
SELECT @a;

@a: This kind of variable needs to add the "@" symbol in front of the variable name, which is called a user session variable, which means that it has a role in the entire session process, which is similar to a global variable.

@@global.sort_buffer_size : This kind of "@@" symbol before the variable is called a system variable


3.6.4. case structure

Grammatical structures :

方式一 : 

CASE case_value

  WHEN when_value THEN statement_list
  
  [WHEN when_value THEN statement_list] ...
  
  [ELSE statement_list]
  
END CASE;

----传递一个int类型的数字 如果为1 则输出星期一  
方式二 : 返回  

CASE

  WHEN search_condition THEN statement_list
  
  [WHEN search_condition THEN statement_list] ...
  
  [ELSE statement_list]
  
END CASE;

Requirement: Given a month, then calculate the quarter it is in  
 

Example: two ways

delimiter $
create procedure p08(month int)
begin
  declare result varchar(20);
  case 
    when month >= 1 and month <=3 then 
      set result = '第一季度';
    when month >= 4 and month <=6 then 
      set result = '第二季度';
    when month >= 7 and month <=9 then 
      set result = '第三季度';
    when month >= 10 and month <=12 then 
      set result = '第四季度';
  end case;
  
  select concat('您输入的月份为 :', month , ' , 该月份为 : ' , result) as content ;
  
end$
delimiter ;

call p08(12);

-- ///

delimiter $
create procedure p09(in m int)
begin
  case m 
	when 1 then SELECT '第一季度';
	when 2 then SELECT '第一季度';
	when 3 then SELECT '第一季度';
	when 4 then SELECT '第二季度';
	when  5 then SELECT '第二季度';
	when 6 then SELECT '第二季度';
	when 7 then SELECT '第三季度';
	when 8 then SELECT '第三季度';
	when 9 then SELECT '第三季度';
	when 10 then SELECT '第四季度';
	when 11 then SELECT '第四季度';
	when 12 then SELECT '第四季度';
   else SELECT '输入有误' ;
	 END case ;
end$
delimiter ;

CALL p09(10);

3.6.5. while loop

Grammatical structures:

while search_condition do

	statement_list
	
end while; --别忘记分号

Requirements: Calculate the sum of numbers added from 1 to n   

Example :

delimiter $
create procedure p10(n int)
begin
  declare total int default 0;
  declare num int default 1;
  while num<=n do
    set total = total + num;
	set num = num + 1;
  end while;
  select total;
end$
delimiter ;

CALL p10(100);

3.6.6.repeat structure

A conditional loop control statement that exits the loop when the condition is met . While is executed when the condition is met, repeat is to exit the loop when the condition is met.

Grammatical structures :

REPEAT

  statement_list

  UNTIL search_condition  --不要加分号

END REPEAT;

Requirements: Calculate the value added from 1 to n 

Example :

-- repeat 结构
delimiter $
create procedure p11(n int)
begin
  declare total int default 0;
  repeat 
    set total = total + n;
    set n = n - 1;
    until n=0  
  end repeat;
  select total ;
end$
delimiter ;

call p11(100);

3.6.7. Cursor/Cursor

Cursor is a data type used to store query result sets , and cursors can be used in stored procedures and functions to cycle through result sets. The use of the cursor includes the declaration of the cursor, OPEN, FETCH and CLOSE, and their syntaxes are as follows.

Declare the cursor:

DECLARE cursor_name CURSOR FOR select_statement ; -- select语句

OPEN cursor:

OPEN cursor_name ;

FETCH cursor:

FETCH cursor_name INTO var_name [, var_name] ...

CLOSE cursor:

CLOSE cursor_name ;

Example :

Initialization script:

create table emp(
  id int(11) not null auto_increment ,
  name varchar(50) not null comment '姓名',
  age int(11) comment '年龄',
  salary int(11) comment '薪水',
  primary key(`id`)
)engine=innodb default charset=utf8 ;

insert into emp(id,name,age,salary) values(null,'金毛狮王',55,3800),(null,'白眉鹰王',60,4000),(null,'青翼蝠王',38,2800),(null,'紫衫龙王',42,1800);

create PROCEDURE p13()
begin
     DECLARE n varchar(20);
	 DECLARE s int;
	 DECLARE has_data int default 1; -- 判断游标中是否还有数据
	 -- 声明游标
     DECLARE my CURSOR for select name,salary from emp;
	 -- 
	 DECLARE EXIT HANDLER FOR NOT FOUND set has_data = 0;
	 create table if not EXISTS tb_my(
		 id int primary key  auto_increment,
		 name varchar(20),
		 salary int
	 );
	 
	 -- 开启游标-- 
	 open my;
	 
	 while has_data=1 do
	    -- 取出游标的数据 
	    FETCH my INTO n,s;
			insert into tb_my(name,salary) values(n,s);
	 end while;
   
   close my;
end;

call p13();

Use mybatis to call to the stored procedure.

Through the loop structure, get the data in the cursor:

DELIMITER $

create procedure pro_test12()
begin
  DECLARE id int(11);
  DECLARE name varchar(50);
  DECLARE age int(11);
  DECLARE salary int(11);
  DECLARE has_data int default 1;
  
  DECLARE emp_result CURSOR FOR select * from emp;
  -- 若没有数据返回,程序继续,并将变量has_data设为0 
  DECLARE EXIT HANDLER FOR NOT FOUND set has_data = 0;
  
  open emp_result;
  
  repeat 
    fetch emp_result into id , name , age , salary;
    select concat('id为',id, ', name 为' ,name , ', age为 ' ,age , ', 薪水为: ', salary);
    until has_data = 0
  end repeat;
  
  close emp_result;
end$

DELIMITER ; 

 How to call stored procedure in java

<mapper namespace="com.aaa.qy160springsecurity03.dao.EmpDao">

 <select id="find" parameterType="java.util.Map" resultType="com.aaa.qy160springsecurity03.entity.Emp" statementType="CALLABLE">
      {
        call p7(#{name,jdbcType=VARCHAR ,mode=IN})
      }
 </select>
</mapper>

3.7. Stored function---stored procedure function: the function has a return value

Note: mysql5.8 needs to set the following content

SET GLOBAL log_bin_trust_function_creators = 1;

Grammatical structure: public return type function name (parameter) {}

CREATE FUNCTION function_name([param type ... ]) 
RETURNS type 
BEGIN
	...
END;

Case :

Define a stored function that requests the total number of records that meet the condition;

delimiter $

create function count_city(countryId int)
returns int
begin
  declare cnum int ;
  
  select count(*) into cnum from city where country_id = countryId;
  
  return cnum;
end$

delimiter ;

transfer:

select count_city(1);

select count_city(2);

4. Index

4.1. Index overview

MySQL's official definition of index is: index (index) is a data structure (ordered) that helps MySQL efficiently obtain data. In addition to data, the database system also maintains data structures that satisfy specific search algorithms. These data structures refer to (point to) data in a certain way, so that efficient search algorithms can be implemented on these data structures. This data structure is an index . . As shown in the diagram below :

Index is a data structure B+Tree, in order to improve the efficiency of database query data.

On the left is the data table, with three columns and 10 records in total. The leftmost is the physical address of the data record (note that logically adjacent records are not necessarily physically adjacent on the disk). In order to speed up the age search, a binary search tree shown on the right can be maintained. Each node contains an index key value and a pointer to the physical address of the corresponding data record, so that the corresponding data can be quickly obtained by using the binary search.

Generally speaking, the index itself is also very large, and it is impossible to store all of it in memory, so the index is often stored on the disk in the form of an index file. Indexes are the most common means used in databases to improve performance .


4.2. Index advantages and disadvantages


4.3. Index structure

Indexes are implemented in MySQL's storage engine layer, not in the service layer. Therefore, the indexes of each storage engine are not necessarily identical, and not all storage engines support all index types. MySQL currently provides the following four index structure algorithms:

  • B+TREE index: The most common index type, most indexes support B-tree index.

  • HASH index: only supported by the Memory engine, and the usage scenarios are simple.

  • R-tree index (spatial index): Spatial index is a special index type of MyISAM engine, which is mainly used for geospatial data types. It is usually used less and is not specially introduced.

  • Full-text (full-text index inverted index--ES): Full-text index is also a special index type of MyISAM, mainly used for full-text indexing. InnoDB supports full-text indexing from Mysql5.6 version.

                  MyISAM, InnoDB, Memory three storage engines support various index types
index NNODB engine MYISAM engine MEMORY engine
B+TREE index support support support
HASH index not support not support support
R-tree index not support support not support
Full-text Supported after version 5.6 support not support

The index we usually refer to, if not specified, refers to the index organized by the B+ tree (multi-way search tree, not necessarily binary). Among them, the clustered index, compound index, prefix index, and unique index all use the B+tree index structure by default, collectively referred to as the index.

4.3.1. Binary tree

4.3.2. B-TREE structure

dynamic presentation

tree demo address

What is a B-tree

4.3.3.B+Tree structure-->Mysql

 What is a B+ tree

4.3.4. The structure of B+tree in the database

BTree: n-level stores n-1 elements and can have n children. Mount the corresponding data in each element.

B+Tree: Store n-1 elements at level n, and can have n children. All elements are in the leaf node, and the leaf node is a closed-loop doubly linked list

4.4. Index classification

For example:

think: 

The id query is faster, and all data can be directly queried according to the id; according to the name, it is also necessary to return to the table to query the id


4.5. Index syntax 

example:



SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int(11) NOT NULL,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `profession` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `gender` tinyint(4) NULL DEFAULT NULL,
  `status` tinyint(4) NULL DEFAULT NULL,
  `createtime` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '吕布', '17799990000', '[email protected]', '软件工程', 23, 1, 6, '2001-02-02 00:00:00');
INSERT INTO `student` VALUES (2, '曹操', '17799990001', '[email protected]', '通信工程', 33, 1, 0, '2001-03-05 00:00:00');
INSERT INTO `student` VALUES (3, '赵云', '17799990002', '[email protected]', '英语', 34, 1, 2, '2002-03-02 00:00:00');
INSERT INTO `student` VALUES (4, '孙悟空', '17799990003', '[email protected]', '工程造价', 54, 1, 0, '2001-07-02 00:00:00');
INSERT INTO `student` VALUES (5, '花木兰', '17799990004', '[email protected]', '软件工程', 23, 2, 1, '2001-04-22 00:00:00');
INSERT INTO `student` VALUES (6, '大乔', '17799990005', '[email protected]', '舞蹈', 22, 2, 0, '2001-02-07 00:00:00');
INSERT INTO `student` VALUES (7, '露娜', '17799990006', '[email protected]', '应用数学', 24, 2, 0, '2001-02-08 00:00:00');
INSERT INTO `student` VALUES (8, '程咬金', '17799990007', '[email protected]', '化工', 38, 1, 5, '2001-05-23 00:00:00');
INSERT INTO `student` VALUES (9, '项羽', '17799990008', '[email protected]', '金属材料', 43, 1, 0, '2022-08-25 17:00:45');
INSERT INTO `student` VALUES (10, '白起', '17799990009', '[email protected]', '机械工程及其自动化', 27, 1, 2, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (11, '韩信', '17799990010', '[email protected]', '无机非金属材料工程', 27, 1, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (12, '荆轲', '17799990011', '[email protected]', '会计', 29, 1, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (13, '兰陵王', '17799990012', '[email protected]', '工程造价', 44, 1, 1, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (14, '狂铁', '17799990013', '[email protected]', '应用数学', 43, 1, 2, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (15, '貂蝉', '17799990014', '[email protected]', '软件工程', 40, 2, 3, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (16, '妲己', '17799990015', '[email protected]', '软件工程', 31, 2, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (17, '芈月', '17799990016', '[email protected]', '工业经济', 35, 2, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (18, '嬴政', '17799990017', '[email protected]', '化工', 38, 1, 1, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (19, '狄仁杰', '17799990018', '[email protected]', '国际贸易', 30, 1, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (20, '安琪拉', '17799990019', '[email protected]', '城市规划', 51, 2, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (21, '典韦', '17799990020', '[email protected]', '城市规划', 52, 1, 2, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (22, '廉颇', '17799990021', '[email protected]', '土木工程', 19, 1, 3, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (23, '后裔', '17799990022', '[email protected]', '城市园林', 20, 1, 0, '2022-08-25 17:23:51');
INSERT INTO `student` VALUES (24, '姜子牙', '17799990023', '[email protected]', '工程造价', 29, 1, 4, '2022-08-25 17:23:51');

SET FOREIGN_KEY_CHECKS = 1;

 need:

-- 1. name字段为姓名字段,该字段的值可能会重复,为该字段创建索引。
CREATE INDEX name_index on student(name); -- 单值索引【普通索引】

-- 2. phone手机号字段的值,是非空,且唯一的,为该字段创建唯一索引。
CREATE UNIQUE INDEX phone_index on student(phone); -- 唯一索引

-- 3. 为profession、age、status创建联合索引。
CREATE INDEX pro_age_status_index on student(profession,age,status); -- 复合索引【组合索引】

-- 4. 为email建立合适的索引来提升查询效率。
CREATE INDEX email_index on student(email); -- 普通索引

SQL optimization: add indexes for corresponding columns

4.6. Performance analysis

Modify in Windows---"my.ini

Check whether the slow query log is enabled

show VARIABLES like 'slow_quert_log'

You can know which sql statement executes slowly by querying the slow query log

Environmental preparation

CREATE TABLE `t_role` (
  `id` varchar(32) NOT NULL,
  `role_name` varchar(255) DEFAULT NULL,
  `role_code` varchar(255) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_role_name` (`role_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `t_user` (
  `id` varchar(32) NOT NULL,
  `username` varchar(45) NOT NULL,
  `password` varchar(96) NOT NULL,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_user_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `user_role` (
  `id` int(11) NOT NULL auto_increment ,
  `user_id` varchar(32) DEFAULT NULL,
  `role_id` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_ur_user_id` (`user_id`),
  KEY `fk_ur_role_id` (`role_id`),
  CONSTRAINT `fk_ur_role_id` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_ur_user_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;




insert into `t_user` (`id`, `username`, `password`, `name`) values('1','super','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe','超级管理员');
insert into `t_user` (`id`, `username`, `password`, `name`) values('2','admin','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe','系统管理员');
insert into `t_user` (`id`, `username`, `password`, `name`) values('3','ykq','$2a$10$8qmaHgUFUAmPR5pOuWhYWOr291WJYjHelUlYn07k5ELF8ZCrW0Cui','test02');
insert into `t_user` (`id`, `username`, `password`, `name`) values('4','stu1','$2a$10$pLtt2KDAFpwTWLjNsmTEi.oU1yOZyIn9XkziK/y/spH5rftCpUMZa','学生1');
insert into `t_user` (`id`, `username`, `password`, `name`) values('5','stu2','$2a$10$nxPKkYSez7uz2YQYUnwhR.z57km3yqKn3Hr/p1FR6ZKgc18u.Tvqm','学生2');
insert into `t_user` (`id`, `username`, `password`, `name`) values('6','t1','$2a$10$TJ4TmCdK.X4wv/tCqHW14.w70U3CC33CeVncD3SLmyMXMknstqKRe','老师1');



INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('5','学生','student','学生');
INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('7','老师','teacher','老师');
INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('8','教学管理员','teachmanager','教学管理员');
INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('9','管理员','admin','管理员');
INSERT INTO `t_role` (`id`, `role_name`, `role_code`, `description`) VALUES('10','超级管理员','super','超级管理员');


INSERT INTO user_role(id,user_id,role_id) VALUES(NULL, '1', '5'),(NULL, '1', '7'),(NULL, '2', '8'),(NULL, '3', '9'),(NULL, '4', '8'),(NULL, '5', '10') ;

 Generally speaking, we need to ensure that the query reaches at least the range level, preferably ref.

 

4.7. Index usage rules

Note: Why is the query based on id not performing a covering index.

How to avoid index failure---measures.

  1. The joint index must follow the leftmost prefix rule

  2. Do not perform operations on indexed columns

  3. Try to match right when fuzzy query

  4. do not select *

  5. If there is no index on the right side during or connection, all indexes will be invalid

  6. The index of the string type must be added with a ''

Guess you like

Origin blog.csdn.net/WQGuang/article/details/132190654