当前位置:网站首页>Interpretation of MySQL optimization principle

Interpretation of MySQL optimization principle

2022-07-07 08:57:00 Please Sit Down

SQL Common commands :
	mysqladmin --version   						:   see mysql edition 
	service mysql start  						:   start-up mysql
	service mysql stop  						:   close mysql
	service mysql restart  						:   restart mysql
	mysql -u  user name  -p  password 						:   land mysql
	show variables like '%char%' ;  			:   see mysql Character encoding 
	show engines ;								:   Check out the database supported engines 
	show variables like '%storage_engine%' ;  	:   Check out the engines currently in use 
	show global status like 'Innodb_page_size';	:   see mysql Size of leaf node 
	 Create index :
			 Mode one :create  Index type    Index name   on  surface ( Field );
			 Mode two :alter table  Table name   Index type    Index name ( Field );
				 Index type  : null > system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
	 Delete index :
			drop index  Index name  on  Table name  ;
			alter table  Table name  drop index  Index name ;
	 Query index :
			show index from  Table name  ;
			show index from  Table name  \G
	 Check whether the slow query log is enabled  : {  Slow query log :MySQL A type of logging provided , Used to record MySQL A response time that exceeds the threshold SQL sentence  (long_query_time, Default 10 second )}
			show variables like '%slow_query_log%' ;
	 Temporarily set slow query log on :( When the service is turned off, it turns off by default )
				 Mode one : set global slow_query_log = 1 ;  -- Turn on in memory 
				 Mode two :  Set in the configuration file 
	 Check the slow query threshold :
			show variables like '%long_query_time%' ;
			 Temporarily set the threshold :set global long_query_time = 5 ; -- After setting up , It takes effect after re login  ( No need to restart the service )
			 Permanently set the threshold : Set... In the configuration file 
			 Query for..., which exceeds the threshold SQL:  show global status like '%slow_queries%' ;
	 Analyzing massive data :
		(1)profiles
			show profiles ; -- Off by default 
			show variables like '%profiling%';
			set profiling = on ;
			show profiles ;   Will record all profiling All after opening SQL Time spent on query statements . shortcoming :  Imprecise , You can only see the total time spent , You can't see the consumption time of each hardware (cpu  io)
		(2) Precise analysis : sql The diagnosis 
			 show profile all for query  The query in the previous step Query_Id
			 show profile cpu,block io for query  The query in the previous step Query_Id
		(3) Global query log  : Record... After opening   All SQL sentence . ( This global record operation   Just tuning 、 Just open it during the development process , In the final deployment implementation   Be sure to close )
			show variables like '%general_log%';
			-- Mode one : All that is done SQL Record in a table 
				set global general_log = 1 ;-- Open global log 
				set global log_output='table' ; -- Set up   It will be all SQL  Record in a table 
			-- Mode two : All that is done SQL Record it in a file 
				set global log_output='file' ;
				set global general_log = on ;
				set global general_log_file='/tmp/general.log' ;
			 After opening , Will record all SQL :  Will be recorded  mysql.general_log In the table .
				select * from  mysql.general_log ;
	 Lock the watch :
		lock table  Table name  read/write ;   read / Write 
	 Unlock the watch :
		lock tables;
	 See which tables are locked :
		show open tables ;  1 Represents being locked 
			 Analyze the severity of table locking : show status like 'table%' ;
				Table_locks_immediate : That is, the number of locks that may be obtained 
				Table_locks_waited: Number of table locks to wait ( If the value is larger , It indicates that the greater the lock competition )
	 Set auto submit off :
		set autocommit =0 ;
	 Line lock analysis :
		show status like '%innodb_row_lock%' ;
			Innodb_row_lock_current_waits 	:  The number of locks currently waiting 
			Innodb_row_lock_time			: The total waiting time . From system startup to now   The total waiting time 
			Innodb_row_lock_time_avg  		: Average waiting time . Average waiting time from system startup to now 
			Innodb_row_lock_time_max  		: Maximum waiting time . Maximum waiting time from system startup to now 
			Innodb_row_lock_waits 			: Number of waits . The total number of times to wait since the system was started 

1.MySQL edition

5.x:
5.0-5.1: Continuation of early products , Upgrade maintenance 
5.4 - 5.x :  MySQL Integrating new storage engines from third-party companies  ( recommend 5.5)
 install :rpm -ivh rpm The software name 
 If installed   With some software   xxx Conflict , You need to uninstall the conflicting software :
	yun -y remove xxx
 When installing   There are log prompts that we can change the password :/usr/bin/mysqladmin -u root password 'new-password'

 Be careful :
	 If you are prompted “GPG keys...” Installation failed , Solution :
		rpm -ivh rpm The software name   --force --nodoeps

 verification :
mysqladmin --version

 start-up mysql application : service mysql start
 close : service mysql stop
 restart : service mysql restart

 In the computer reboot after   land MySQL :  mysql
 There may be a mistake :   "/var/lib/mysql/mysql.sock non-existent "
-- reason : yes Mysql The service did not start 
 solve  :   Start the service : 1. Before each use   Start service manually    /etc/init.d/mysql start
	  	 2. Boot from boot    chkconfig mysql on     ,  chkconfig mysql off
	 Check whether the machine starts automatically : ntsysv

 to mysql  Super administrator of root  Add password :/usr/bin/mysqladmin -u root password root

 land :
mysql -u root -p
 Database storage directory :
ps -ef|grep mysql   You can see :
	 Database directory :     datadir=/var/lib/mysql
	pid File directory : --pid-file=/var/lib/mysql/bigdata01.pid

	MySQL Core catalog :
		/var/lib/mysql :mysql  The installation directory 
		/usr/share/mysql:   The configuration file 
		/usr/bin: Command directory (mysqladmin、mysqldump etc. )
		/etc/init.d/mysql Start stop script 

  MySQL The configuration file 
		 my-huge.cnf	 High end servers   1-2G Memory 
		 my-large.cnf    Medium scale 
		 my-medium.cnf   commonly 
		 my-small.cnf    smaller 
		 however , Configuration files above mysql Default does not recognize , Only recognized by default  /etc/my.cnf
		 use  my-huge.cnf :
		cp /usr/share/mysql/my-huge.cnf /etc/my.cnf
		 Be careful :mysql5.5 Default profile /etc/my.cnf;Mysql5.6  Default profile /etc/mysql-default.cnf

 Default port 3306

mysql Character encoding :
	sql  :  show variables like '%char%' ;
	 It can be found that part of the code is  latin, It needs to be set to utf-8
	 Set encoding :
	vi /etc/my.cnf:
	[mysql]
	default-character-set=utf8
	[client]
	default-character-set=utf8

	[mysqld]
	character_set_server=utf8
	character_set_client=utf8
	collation_server=utf8_general_ci

 restart Mysql:  service mysql restart
	sql  :  show variables like '%char%' ;
 matters needing attention : Modify encoding   Only right “ after ” The created database takes effect , therefore   We suggest   stay mysql After installation , first time   Unified coding .

mysql: Clear the screen     ctrl+L    , system clear

2. principle

  MYSQL Logical layering  : adjoining course   Service layer   Engine layer   Storage layer 
  InnoDB( Default ) : Business first  ( Suitable for high concurrent operation ; Row lock )
  MyISAM : Performance priority   ( Table locks )

 Query database engine :  
		 Which engines are supported ? show engines ;
		 Check out the engines currently in use    show variables like '%storage_engine%' ;

 Specify the engine for the database object :
create table tb(
	id int(4) auto_increment ,
	name varchar(5),
	dept varchar(5) ,
	primary key(id)
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8   ;

3.SQL Optimize

 reason : Low performance 、 Execution time is too long 、 The wait is too long 、SQL Poor sentences ( Link query )、 Index failure 、 Unreasonable server parameter setting ( buffer 、 Number of threads )
a.SQL :
	 Writing process :
		select dinstinct  ..from  ..join ..on ..where ..group by ...having ..order by ..limit ..

	 Analytic process :
		from .. on.. join ..where ..group by ....having ...select dinstinct ..order by limit ...
b.SQL Optimize ,  Mainly   Optimizing indexes 
	 Indexes :  It's equivalent to a book catalog 
	 Indexes : index Help MYSQL Data structure for efficient data acquisition . An index is a data structure ( Trees :B Trees ( Default )、Hash Trees ...)

	 Disadvantages of index :
		1. The index itself is big ,  Can be stored in memory / Hard disk ( Usually it is   Hard disk )
		2. Indexes are not applicable in all cases : a. Small amount of data   b. Frequently updated fields    c. Rarely used fields 
		3. The index will reduce the efficiency of addition, deletion and modification ( Additions and deletions    check )

	 advantage :1 Improve query efficiency ( Reduce IO Usage rate )
	      2. Reduce CPU Usage rate  (...order by age desc, because  B Tree index   Is itself a   Well ordered structure , So when sorting    You can use it directly )

https://www.cnblogs.com/annsshadow/p/5037667.html

4. Indexes

 classification :
	 primary key :   Can't repeat .id     It can't be null
	 unique index   : Can't repeat .id     It can be null
	 Single value index   :  Single column , age ; A table can have multiple single valued indexes ,name.
	 Composite index   : Index of multiple columns  ( amount to   Two level directory  :  z: zhao)  (name,age)   (a,b,c,d,...,n)
 Create index :
	 Mode one :
        create  Index type    Index name   on  surface ( Field )
         Single value :
        create index   dept_index on  tb(dept);
         only :
        create unique index  name_index on tb(name) ;
         Composite index 
        create index dept_name_index on tb(dept,name);
	 Mode two :
		alter table  Table name   Index type    Index name ( Field )
         Single value :
        alter table tb add index dept_index(dept) ;
         only :
        alter table tb add unique index name_index(name);
         Composite index 
        alter table tb add index dept_name_index(dept,name);

	 Be careful : If a field is primary key, The default field is   primary key 

 Delete index :
	drop index  Index name  on  Table name  ;
	drop index name_index on tb ;

 Query index :
	show index from  Table name  ;
	show index from  Table name  \G

5.SQL Performance issues

a. analysis SQL Implementation plan of : explain , Can simulate SQL Optimizer execution SQL sentence , So that developers Know what you wrote SQL condition
b.MySQL Query optimization, which interferes with our optimization

 An optimization method , Official website :https://dev.mysql.com/doc/refman/5.5/en/optimization.html


 Query execution plan :  explain +SQL sentence 
		explain  select  * from tb ;

+----+-------------+-------+--------+---------------+------+---------+------+------+----------+
| id | select_type | table | type   | possible_keys | key  | key_len | ref  | rows | Extra    |
+----+-------------+-------+--------+---------------+------+---------+------+------+----------+

 id 			:  Number 
 select_type 	: Query type 
 table 			: surface 
 type  			: type 
 possible_keys 	: The index used in the forecast 
 key 			: Actual index used 
 key_len 		: The length of the actual index used 
 ref  			:  References between tables 
 rows 			: The amount of data that can be queried by index 
 Extra     		:  Additional information 

Prepare the data :

create table course	(
    cid int(3),
    cname varchar(20),
    tid int(3)
);
create table teacher(
    tid int(3),
    tname varchar(20),
    tcid int(3)
);
create table teacherCard	(
    tcid int(3),
    tcdesc varchar(200)
);

insert into course values(1,'java',1);
insert into course values(2,'html',1);
insert into course values(3,'sql',2);
insert into course values(4,'web',3);

insert into teacher values(1,'tz',1);
insert into teacher values(2,'tw',2);
insert into teacher values(3,'tl',3);

insert into teacherCard values(1,'tzdesc') ;
insert into teacherCard values(2,'twdesc') ;
insert into teacherCard values(3,'tldesc') ;
 The course number is 2   or   The teacher's certificate number is 3   Teacher information 
explain + sql:
	explain select t.* from teacher t ,course c ,teacherCard tc where t.tid=c.tid and t.tcid=tc.tcid and (c.cid=2 or tc.tcid=3);

id

①:id Same value , From the top down   Sequential execution .
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
		| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
		|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                |
		|  1 | SIMPLE      | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using join buffer |
		|  1 | SIMPLE      | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
			t-tc-c : 3-3-4
 After adding three pieces of data :
	insert into teacher values(4,'ta',4);
    insert into teacher values(5,'tb',5);
    insert into teacher values(6,'tc',6);

+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                |
|  1 | SIMPLE      | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where; Using join buffer |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
tc-c-t : 3-4-6

	 The execution order of the table    The reason for the change due to the change of quantity :  Cartesian product 
			a 	b    c
			4	3	 2   =  		2*3=6 * 4   =24
									3*4=12* 2   =24

	 A table with small data   Priority query ;

②:id Values are different :id The higher the value, the higher the priority query  ( The essence : In nested subqueries , Check the inner layer first   Check the outer layer again )

	 Inquire about Professor SQL Description of the teacher of the course (desc)
	explain select tc.tcdesc from teacherCard tc,course c,teacher t where c.tid = t.tid and t.tcid = tc.tcid and c.cname = 'sql' ;

	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
	| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
	|  1 | SIMPLE      | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                |
	|  1 | SIMPLE      | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
	|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where; Using join buffer |
	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+

		tc-c-t : 3-4-6

	 Will be more than   Multi-table query   Convert to sub query form :

	explain select tc.tcdesc from teacherCard tc where tc.tcid =
	(select t.tcid from teacher t where  t.tid =
		(select c.tid from course c where c.cname = 'sql')
	);

	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	|  1 | PRIMARY     | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
	|  2 | SUBQUERY    | t     | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where |
	|  3 | SUBQUERY    | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
	+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

		c-t-tc : 4-6-3

	 Subquery + Multiple tables :
	explain select t.tname ,tc.tcdesc from teacher t,teacherCard tc where t.tcid= tc.tcid
	and t.tid = (select c.tid from course c where cname = 'sql') ;

	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
	| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
	|  1 | PRIMARY     | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                |
	|  1 | PRIMARY     | t     | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where; Using join buffer |
	|  2 | SUBQUERY    | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where                    |
	+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+

		c-tc-t : 4-3-6

	 Conclusion : id Values have the same , There are also differences. : id The higher the value, the higher the priority ;id Same value , From the top down   Sequential execution 

select_type

Query type

SUBQUERY(subquery): Include subqueries SQL Medium   Subquery  ( Not the outermost layer ) or   The first of the inner queries SELECT, The result does not depend on the external query result set ( Will not be overwritten by the database engine );
PRIMARY(primary):  Include subqueries SQL Medium   Main query  ( Outermost layer )

 The first two examples :	explain select tc.tcdesc from teacherCard tc where tc.tcid = (select t.tcid from teacher t where  t.tid = (select c.tid from course c where c.cname = 'sql'));
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | PRIMARY     | tc    | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
|  2 | SUBQUERY    | t     | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where |
|  3 | SUBQUERY    | c     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
SIMPLE(simple):  Simple query ( Does not contain subqueries 、union)

 Example : explain select * from teacher;
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | teacher | ALL  | NULL          | NULL | NULL    | NULL |    6 |       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------+
DERIVED(derived):  Derived query ( Used a temporary watch )( That is, the results found in the table continue to query the results in this table )

a. stay from There is only one table in the subquery 
     Example : explain select cr.cname from ( select * from course where tid in (1,2)) cr ;
    +----+-------------+------------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+------------+------+---------------+------+---------+------+------+-------------+
    |  1 | PRIMARY     | <derived2> | ALL  | NULL          | NULL | NULL    | NULL |    3 |             |
    |  2 | DERIVED     | course     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
    +----+-------------+------------+------+---------------+------+---------+------+------+-------------+
     remarks :id=1 Medium table=<derived2> This record derived Represents a derived table ,2 Said is id=2 This record of 

b. stay from Sub query ,  If there is table1 union table2 , be table1  Namely derived,table2 Namely union
     Example : explain select  cr.cname 	from ( select * from course where tid = 1  union select * from course where tid = 2 ) cr ;
    +----+--------------+------------+------+---------------+------+---------+------+------+-------------+
    | id | select_type  | table      | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+--------------+------------+------+---------------+------+---------+------+------+-------------+
    |  1 | PRIMARY      | <derived2> | ALL  | NULL          | NULL | NULL    | NULL |    3 |             |
    |  2 | DERIVED      | course     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
    |  3 | UNION        | course     | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
    | NULL | UNION RESULT | <union2,3> | ALL  | NULL          | NULL | NULL    | NULL | NULL |             |
    +----+--------------+------------+------+---------------+------+---------+------+------+-------------+
     remarks : inform id=2(course) and id=3(course) Between tables union Inquire about ( The joint query ),id=1 The table of is a temporary table with a derived query of id=2 Value ,id=3 Representation table 3 Is a joint table 
UNION(union): UNION  first SELECT  by PRIMARY, The second and all subsequent SELECT  by  UNION SELECT TYPE; The joint query ( The above example )
UNION RESULT(union result) : After each result set is taken out , Can merge , This operation is  UNION RESULT;	( The above example )
DEPENDENT UNION, In subquery UNION operation , from UNION  The second and all subsequent SELECT Of the statement SELECT TYPE by  DEPENDENT UNION, This is generally similar to DEPENDENT SUBQUERY Combined application , Sub query UNION  The first one is DEPENDENT SUBQUERY;
DEPENDENT SUBQUERY, The first inner layer in a subquery SELECT, Depends on the result set of the external query ;
MATERIALIZED, Subquery materialization , The table appears in an unrelated subquery   And when it needs to be materialized, there will be MATERIALIZED key word ;
UNCACHEABLE SUBQUERY, Subqueries that result sets cannot cache , You need to query one by one ;
UNCACHEABLE UNION, Indicates that the subquery cannot be materialized   It needs to be run one by one .
null > system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

type

Index type 、 type

Common in enterprises : system>const>eq_ref>ref>range>index>all , Right type The premise of optimization : There is an index
among :system,const It's just an ideal situation ; Can actually achieve ref>range

system

A system table with only one piece of data or The derived table has only one main query of data ( Ignore , Basically can't reach )

 Example ( The derived table has only one main query of data ):
create table test01 ( tid int(3), tname varchar(20) );
insert into test01 values(1,'a') ;
commit;

 Add index :
alter table test01 add constraint tid_pk primary key(tid) ;
explain select * from (select * from test01 )t where tid =1 ;
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL | NULL    | NULL |    1 |       |
|  2 | DERIVED     | test01     | ALL    | NULL          | NULL | NULL    | NULL |    1 |       |
+----+-------------+------------+--------+---------------+------+---------+------+------+-------+
 remarks : system Index of level type 

const

Only one piece of data can be found SQL , be used for Primary key or unique Indexes ( The type is related to the index type )
Constant query of primary key or unique index , The maximum number of tables is 1 The row record matches the query , Usually const Use the primary key or unique index for fixed value query .( Constant queries are very fast )

 Example : explain select tid from test01 where tid =1 ;
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table  | type  | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
|  1 | SIMPLE      | test01 | const | PRIMARY       | PRIMARY | 4       | const |    1 | Using index |
+----+-------------+--------+-------+---------------+---------+---------+-------+------+-------------+
 remarks : const Index of level type 

alter table test01 drop primary key ;
create index test01_index on test01(tid) ;
explain select tid from test01 where tid =1 ;
+----+-------------+--------+------+---------------+--------------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key          | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+--------------+---------+-------+------+-------------+
|  1 | SIMPLE      | test01 | ref  | test01_index  | test01_index | 4       | const |    1 | Using index |
+----+-------------+--------+------+---------------+--------------+---------+-------+------+-------------+
 remarks : index( commonly ) Index of level type 

eq_ref

Uniqueness index : For each index key query , Return matching unique row data ( Yes and only 1 individual , Not much 、 You can't 0)
select … from …where name = … . Common in unique indexes And primary key index .

// Set primary key 
alter table teacherCard add constraint pk_tcid primary key(tcid);
// Set up tcid The index of 
alter table teacher add constraint uk_tcid unique index(tcid) ;

explain select t.tcid from teacher t,teacherCard tc where t.tcid = tc.tcid ;
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref          | rows | Extra                    |
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+--------------------------+
|  1 | SIMPLE      | tc    | index | PRIMARY       | PRIMARY | 4       | NULL         |    3 | Using index              |
|  1 | SIMPLE      | t     | ref   | uk_tcid       | uk_tcid | 5       | mydb.tc.tcid |    1 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+--------------+------+--------------------------+

delete from teacher where tcid>3;(teacherCard There are only 3 Data )
explain select t.tcid from teacher t,teacherCard tc where t.tcid = tc.tcid ;
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref         | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+-------------+
|  1 | SIMPLE      | t     | index  | uk_tcid       | uk_tcid | 5       | NULL        |    3 | Using index |
|  1 | SIMPLE      | tc    | eq_ref | PRIMARY       | PRIMARY | 4       | mydb.t.tcid |    1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+-------------+------+-------------+

 above SQL, The index used is  t.tcid, namely teacher In the table tcid Field ;
 If teacher Number of data in the table   and   The number of data in the connection query is consistent ( All are 3 Data ), It is possible to satisfy eq_ref Level ; Otherwise, it can't be satisfied .

ref

Non unique index , For each index key query , Return all matching lines (0, many )

 Prepare the data :
	 insert into teacher values(4,'tz',4) ;
	 insert into teacherCard values(4,'tz222');
 test :
// to name Set general index 
alter table teacher add index index_name (tname) ;
explain select * from teacher 	where tname = 'tz';
+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key        | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+
|  1 | SIMPLE      | teacher | ref  | index_name    | index_name | 63      | const |    2 | Using where |
+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+

range

Retrieve the specified range of rows ,where After that is a range query (between ,> < >=, special :in Sometimes it fails , It turns into No index all)

​ When the predicate uses the index range query :=、<>、>、>=、<、<=、IS NULL、BETWEEN、IN、<=> ( This is an expression : The left can push out the right , The right side can also push out the left )

alter table teacher add index tid_index (tid) ;
explain select t.* from teacher t where t.tid in (1,2) ;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | ALL  | tid_index     | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
explain select t.* from teacher t where t.tid <3 ;
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | range | tid_index     | tid_index | 5       | NULL |    1 | Using where |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+

index

Query all data in the index
Use to index , But not index lookup , Instead, do a scan of the index tree , Even index scanning , In most cases, it is also better than full table scanning , Because the key value on the index tree is only the key value of the index column + Primary key , The full table scan is in Clustered index tree ( Primary key + All columns ) Scan up , The index tree is much thinner and much smaller .

explain select tid from teacher ;  --tid  It's the index ,  Just scan the index table , You don't need all the data in all the tables 
+----+-------------+---------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key       | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | teacher | index | NULL          | tid_index | 5       | NULL |    4 | Using index |
+----+-------------+---------+-------+---------------+-----------+---------+------+------+-------------+

all

Query the data in all tables

explain select cid from course ;  --cid It's not an index , Need a full list of all , That is, all data in all tables is required 
+----+-------------+--------+------+---------------+------+---------+------+------+-------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | course | ALL  | NULL          | NULL | NULL    | NULL |    4 |       |
+----+-------------+--------+------+---------------+------+---------+------+------+-------+

system/const

The result is just one piece of data

eq_ref

There are many results ; But every piece of data is unique ;

ref

There are many results ; But every piece of data is 0 Or more ;

Other situations

null:  Do not access any table 
fulltext:  In the process of querying , Using the  fulltext  Indexes (fulltext index stay innodb In the engine , Only 5.6 Support after version )
ref_or_null:  Follow ref The query is similar to , stay ref Based on the query of , But there will be one more null Conditional query of value 
index merg:  When a conditional predicate is used to the leftmost column of multiple indexes and the connection between predicates is or Under the circumstances , Will use   Index union query 
unique subquery: eq_ref A branch of , Query the sub query of the primary key ;
index subquery: ref A branch of , Query sub queries of nonclustered indexes :

possible_keys

Possible indexes , It's a prediction , forbid .

alter table course add index cname_index (cname);

explain select t.tname ,tc.tcdesc from teacher t,teacherCard tc
 where t.tcid= tc.tcid
and t.tid = (select c.tid from course c where cname = 'sql') ;

 If  possible_key/key yes NULL, Then the index is useless 

explain select tc.tcdesc from teacherCard tc,course c,teacher t where c.tid = t.tid
and t.tcid = tc.tcid and c.cname = 'sql' ;

key

Index actually used .

key_len

Length of index .

effect : Used to determine whether a composite index is fully used

create table test_kl(
	name char(20) not null default ''
);
explain select * from test_kl where name ='' ;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test_kl | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
alter table test_kl add index index_name(name) ;
explain select * from test_kl where name ='' ;   -- key_len :60
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+
| id | select_type | table   | type | possible_keys | key        | key_len | ref   | rows | Extra                    |
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+
|  1 | SIMPLE      | test_kl | ref  | index_name    | index_name | 60      | const |    1 | Using where; Using index |
+----+-------------+---------+------+---------------+------------+---------+-------+------+--------------------------+

 stay utf8:1 Character station 3 Bytes 

alter table test_kl add column name1 char(20) ;  --name1 It can be for null
explain select * from test_kl where name1 ='' ;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test_kl | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+

alter table test_kl add index index_name1(name1) ;
explain select * from test_kl where name1 ='' ;

-- If the index field can be Null, Will use 1 Bytes are used to identify ( The ID can be empty )
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key         | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
|  1 | SIMPLE      | test_kl | ref  | index_name1   | index_name1 | 61      | const |    1 | Using where |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+

drop index index_name on test_kl ;
drop index index_name1 on test_kl ;

 Add a composite index 
alter table test_kl add index name_name1_index (name,name1) ;

explain select * from test_kl where name1 = '' ;   -- key_len: 121
+----+-------------+---------+-------+---------------+------------------+---------+------+------+--------------------------+
| id | select_type | table   | type  | possible_keys | key              | key_len | ref  | rows | Extra                    |
+----+-------------+---------+-------+---------------+------------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | test_kl | index | NULL          | name_name1_index | 121     | NULL |    1 | Using where; Using index |
+----+-------------+---------+-------+---------------+------------------+---------+------+------+--------------------------+
explain select * from test_kl where name = '' ;     -- key_len: 60
+----+-------------+---------+------+------------------+------------------+---------+-------+------+--------------------------+
| id | select_type | table   | type | possible_keys    | key              | key_len | ref   | rows | Extra                    |
+----+-------------+---------+------+------------------+------------------+---------+-------+------+--------------------------+
|  1 | SIMPLE      | test_kl | ref  | name_name1_index | name_name1_index | 60      | const |    1 | Using where; Using index |
+----+-------------+---------+------+------------------+------------------+---------+-------+------+--------------------------+

varchar(20)
// Create a field , And add an index 
alter table test_kl add column name2 varchar(20) ;   -- It can be for Null
alter table test_kl add index name2_index (name2) ;

explain select * from test_kl where name2 = '' ;   --key_len: 63
20*3=60 +  1(null 1 Byte ID can be empty )  +2( use 2 Bytes   Identification variable length )  =63
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key         | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+
|  1 | SIMPLE      | test_kl | ref  | name2_index   | name2_index | 63      | const |    1 | Using where |
+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+

utf8:1 Characters 3 Bytes 		20 Characters =20*3=60
gbk:1 Characters 2 Bytes 		20 Characters =20*2=40
latin:1 Characters 1 Bytes 	20 Characters =20*1=20

ref

Pay attention to and type Medium ref Value differentiation .

effect : Indicates the current table Reference Field .

select ....where a.c = b.x ;( among b.x It can be a constant ,const)
alter table course  add index tid_index (tid) ;
explain select * from course c,teacher t where c.tid = t.tid  and t.tname ='tw' ;
+----+-------------+-------+------+----------------------+------------+---------+------------+------+-------------+
| id | select_type | table | type | possible_keys        | key        | key_len | ref        | rows | Extra       |
+----+-------------+-------+------+----------------------+------------+---------+------------+------+-------------+
|  1 | SIMPLE      | t     | ref  | index_name,tid_index | index_name | 63      | const      |    1 | Using where |
|  1 | SIMPLE      | c     | ref  | tid_index            | tid_index  | 5       | mydb.t.tid |    1 | Using where |
+----+-------------+-------+------+----------------------+------------+---------+------------+------+-------------+
 remarks : 1,t The table uses a constant (const)
	  2,c The table uses t Tabular id

rows

Query optimized by index The number of data ( Actually found by index The number of data )

explain select * from course c,teacher t  where c.tid = t.tid and t.tname = 'tz' ;

SQL Analytic process :
	from.. on.. join.. where.. group by.. having.. select dinstinct .. order by limit..

Extra

using filesort

High performance consumption ; need " additional " A sort of ( Inquire about ). Common in order by In the sentence ( Before sorting, you must first query )、 Or sorting that cannot be done with indexes

create table test02(
    a1 char(3),
    a2 char(3),
    a3 char(3),
    index idx_a1(a1),
    index idx_a2(a2),
    index idx_a3(a3)
);
explain select * from test02 where a1 ='' order by a1 ;
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table  | type | possible_keys | key    | key_len | ref   | rows | Extra       |
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | test02 | ref  | idx_a1        | idx_a1 | 10      | const |    1 | Using where |
+----+-------------+--------+------+---------------+--------+---------+-------+------+-------------+

explain select * from test02 where a1 ='' order by a2 ; --using filesort
+----+-------------+--------+------+---------------+--------+---------+-------+------+-----------------------------+
| id | select_type | table  | type | possible_keys | key    | key_len | ref   | rows | Extra                       |
+----+-------------+--------+------+---------------+--------+---------+-------+------+-----------------------------+
|  1 | SIMPLE      | test02 | ref  | idx_a1        | idx_a1 | 10      | const |    1 | Using where; Using filesort |
+----+-------------+--------+------+---------------+--------+---------+-------+------+-----------------------------+
 Summary : For single index ,  If sort and find are the same field , Will not appear using filesort; If sort and find are not the same field , It will appear using filesort;
 avoid : where Which fields , Just order by Those fields 

 Composite index : Cannot span columns ( Best left prefix )
drop index idx_a1 on test02;
drop index idx_a2 on test02;
drop index idx_a3 on test02;

alter table test02 add index idx_a1_a2_a3 (a1,a2,a3) ;
explain select *from test02 where a1='' order by a3 ;  --using filesort( Cross column )
+----+-------------+--------+------+---------------+--------------+---------+-------+------+------------------------------------------+
| id | select_type | table  | type | possible_keys | key          | key_len | ref   | rows | Extra                                    |
+----+-------------+--------+------+---------------+--------------+---------+-------+------+------------------------------------------+
|  1 | SIMPLE      | test02 | ref  | idx_a1_a2_a3  | idx_a1_a2_a3 | 10      | const |    1 | Using where; Using index; Using filesort |
+----+-------------+--------+------+---------------+--------------+---------+-------+------+------------------------------------------+

explain select *from test02 where a2='' order by a3 ; --using filesort( Cross column )
explain select *from test02 where a1='' order by a2 ; ( There is no straddle )
explain select *from test02 where a2='' order by a1 ; --using filesort( Cross column )
 Summary : avoid : where and order by  Use in the order of composite indexes , Do not use across columns or out of order .

using temporary

High performance loss , Temporary table used . Generally appears in group by In the sentence .

explain select a1 from test02 where a1 in ('1','2','3') group by a1 ;
+----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+
| id | select_type | table  | type  | possible_keys | key          | key_len | ref  | rows | Extra                    |
+----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | test02 | index | idx_a1_a2_a3  | idx_a1_a2_a3 | 30      | NULL |    1 | Using where; Using index |
+----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+

explain select a1 from test02 where a1 in ('1','2','3') group by a2 ; --using temporary
+----+-------------+--------+-------+---------------+--------------+---------+------+------+-----------------------------------------------------------+
| id | select_type | table  | type  | possible_keys | key          | key_len | ref  | rows | Extra                                                     |
+----+-------------+--------+-------+---------------+--------------+---------+------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | test02 | index | idx_a1_a2_a3  | idx_a1_a2_a3 | 30      | NULL |    1 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+--------+-------+---------------+--------------+---------+------+------+-----------------------------------------------------------+
 avoid : Query those columns , According to those columns  group by .

using index

Performance improvement ; Index overlay ( Overlay index ).

​ reason : Do not read the original file , Get data from index file only ( No need to return table query )

​ As long as the columns used It's all in the index , That's index coverage using index

 for example :test02 There is a composite index in the table (a1,a2,a3)
    explain select a1,a2 from test02 where a1='' or a2= '' ; --using index
    +----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+
    | id | select_type | table  | type  | possible_keys | key          | key_len | ref  | rows | Extra                    |
    +----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+
    |  1 | SIMPLE      | test02 | index | idx_a1_a2_a3  | idx_a1_a2_a3 | 30      | NULL |    1 | Using where; Using index |
    +----+-------------+--------+-------+---------------+--------------+---------+------+------+--------------------------+
    
drop index idx_a1_a2_a3 on test02;
alter table test02 add index idx_a1_a2(a1,a2) ;
explain select a1,a3 from test02 where a1='' or a3= '' ;
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test02 | ALL  | idx_a1_a2     | NULL | NULL    | NULL |    1 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

explain select a1,a2 from test02 where a1='' or a2= '' ;
+----+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
| id | select_type | table  | type  | possible_keys | key       | key_len | ref  | rows | Extra                    |
+----+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
|  1 | SIMPLE      | test02 | index | idx_a1_a2     | idx_a1_a2 | 20      | NULL |    1 | Using where; Using index |
+----+-------------+--------+-------+---------------+-----------+---------+------+------+--------------------------+
explain select a1,a2 from test02  ;
+----+-------------+--------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table  | type  | possible_keys | key       | key_len | ref  | rows | Extra       |
+----+-------------+--------+-------+---------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | test02 | index | NULL          | idx_a1_a2 | 20      | NULL |    1 | Using index |
+----+-------------+--------+-------+---------------+-----------+---------+------+------+-------------+

 If index overrides are used (using index when ), Would be right  possible_keys and key Impact :
	a. without where, Then the index only appears in key in ;
	b. If there is where, Index   Appear in the key and possible_keys in .

using where

​ hypothesis age It's an index column
​ But query statements select age,name from …where age =…, In this statement, you must go back to the original table Name, Therefore, the using where.( Need to return to the table to query )

explain select a1,a3 from test02 where a3 = '' ; --a3 You need to go back to the original table 
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | test02 | ALL  | NULL          | NULL | NULL    | NULL |    1 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

impossible where

where Clause is always false( An impossible result )

explain select * from test02 where a1='x' and a1='y'  ;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+

using join buffer

effect :Mysql The engine is working Connection cache .

6. Optimization case

 Example :
create table test03(
    a1 int(4) not null,
    a2 int(4) not null,
    a3 int(4) not null,
    a4 int(4) not null
);
alter table test03 add index idx_a1_a2_a3_a4(a1,a2,a3,a4);
explain select a1,a2,a3,a4 from test03 where a1=1 and a2=2 and a3=3 and a4=4;
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
| id | select_type | table  | type | possible_keys   | key             | key_len | ref                     | rows | Extra       |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
|  1 | SIMPLE      | test03 | ref  | idx_a1_a2_a3_a4 | idx_a1_a2_a3_a4 | 16      | const,const,const,const |    1 | Using index |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
-- Recommend writing , Because of the order in which the index is used (where The following order ) Consistent with the order of Composite Index 

explain select a1,a2,a3,a4 from test03 where a4=1 and a3=2 and a2=3 and a1=4;
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
| id | select_type | table  | type | possible_keys   | key             | key_len | ref                     | rows | Extra       |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
|  1 | SIMPLE      | test03 | ref  | idx_a1_a2_a3_a4 | idx_a1_a2_a3_a4 | 16      | const,const,const,const |    1 | Using index |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------------------+------+-------------+
-- Although the order of writing is inconsistent with the order of indexing , however SQL Go through before the actual implementation SQL Optimizer tuning , The result is the same as the previous SQL It's consistent 
-- The top two SQL, All composite indexes are used 

explain select a1,a2,a3,a4 from test03 where a1=1 and a2=2 and a4=3 order by a3;
+----+-------------+--------+------+-----------------+-----------------+---------+-------------+------+--------------------------+
| id | select_type | table  | type | possible_keys   | key             | key_len | ref         | rows | Extra                    |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------+------+--------------------------+
|  1 | SIMPLE      | test03 | ref  | idx_a1_a2_a3_a4 | idx_a1_a2_a3_a4 | 8       | const,const |    1 | Using where; Using index |
+----+-------------+--------+------+-----------------+-----------------+---------+-------------+------+--------------------------+
-- The SQL Using the a1 a2 Two indexes , These two fields   No need to return table query using index ;  and a4 Because cross column use , Caused the index to fail , Need to return to the table to query   So it is using where;  The above can be done through  key_len To verify 

explain select a1,a2,a3,a4 from test03 where a1=1 and a4=3 order by a3;
+----+-------------+--------+------+-----------------+-----------------+---------+-------+------+------------------------------------------+
| id | select_type | table  | type | possible_keys   | key             | key_len | ref   | rows | Extra                                    |
+----+-------------+--------+------+-----------------+-----------------+---------+-------+------+------------------------------------------+
|  1 | SIMPLE      | test03 | ref  | idx_a1_a2_a3_a4 | idx_a1_a2_a3_a4 | 4       | const |    1 | Using where; Using index; Using filesort |
+----+-------------+--------+------+-----------------+-----------------+---------+-------+------+------------------------------------------+
-- The SQL There is Using filesort( Sort in file ," One extra search / Sort "), Do not use across columns (where and order by Spell it together , Do not use across columns )( That is to say a1 Go ahead a4 Cross the column and a4 invalid , The next one is order by Yes a3 Reorder across columns , Finally, go back to the database to find a4)

explain select a1,a2,a3,a4 from test03 where a1=1 and a4=3 order by a2,a3; -- Can't using filesort

-- summary :
1, If (a,b,c,d) Composite index   Consistent with the order of use , Then all composite indexes use ( And do not use across columns ). If the parts are consistent ( And do not use across columns ), Use partial index .
2,where and order by Spell it together , Do not use across columns 
			
using temporary: Need to use an extra table .  Generally appears in group by In the sentence ; I already have a watch , But not for , We must have another table .

	 Analytic process :
	from .. on.. join ..where ..group by ....having ...select dinstinct ..order by limit ...
        a.
            explain select * from test03 where a2=2 and a4=4 group by a2,a4 ;-- No, using temporary
        b.
            explain select * from test03 where a2=2 and a4=4 group by a3 ;

SQL :
	 Writing process :
		select dinstinct  ..from  ..join ..on ..where ..group by ...having ..order by ..limit ..

	 Analytic process :
		from .. on.. join ..where ..group by ....having ...select dinstinct ..order by limit ...

 Single table optimization 、 Two table optimization 、 Three table optimization 
(1) Single table optimization 
	create table book(
		bid int(4) primary key,
		name varchar(20) not null,
		authorid int(4) not null,
		publicid int(4) not null,
		typeid int(4) not null
	);

	insert into book values(1,'tjava',1,1,2) ;
	insert into book values(2,'tc',2,1,2) ;
	insert into book values(3,'wx',3,2,1) ;
	insert into book values(4,'math',4,2,3) ;
	commit;

	 Inquire about authorid=1 And  typeid by 2 or 3 Of 	bid
	explain select bid from book where typeid in(2,3) and authorid=1  order by typeid desc ;
	+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
	| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
	+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+
	|  1 | SIMPLE      | book  | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using filesort |
	+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------+

	 Optimize : Suo Yin 
	alter table book add index idx_bta (bid,typeid,authorid);
	explain select bid from book where typeid in(2,3) and authorid=1  order by typeid desc ;
	+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------------------+
	| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                    |
	+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------------------+
	|  1 | SIMPLE      | book  | index | NULL          | idx_bta | 12      | NULL |    4 | Using where; Using index; Using filesort |
	+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------------------+

	 Once indexed   Upgrade optimization , You need to delete the previously discarded index , To prevent interference .
	drop index idx_bta on book;

	 according to SQL The order of the actual parsing , Adjust the order of the index :
	alter table book add index idx_tab (typeid,authorid,bid); -- Although you can query back to the table bid, But will bid Put it in the index   It can improve the use using index ;
	explain select bid from book where typeid in(2,3) and authorid=1  order by typeid desc ;
	+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
	| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                    |
	+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
	|  1 | SIMPLE      | book  | index | idx_tab       | idx_tab | 12      | NULL |    4 | Using where; Using index |
	+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+

	 Optimize again ( It used to be index Level ): Ideas . Because range queries in Sometimes it will come true , So exchange   Order of indexes , take typeid in(2,3)  To the end .
	drop index idx_tab on book;
	alter table book add index idx_atb (authorid,typeid,bid);
	explain select bid from book where  authorid=1 and  typeid in(2,3) order by typeid desc ;
	+----+-------------+-------+------+---------------+---------+---------+-------+------+--------------------------+
	| id | select_type | table | type | possible_keys | key     | key_len | ref   | rows | Extra                    |
	+----+-------------+-------+------+---------------+---------+---------+-------+------+--------------------------+
	|  1 | SIMPLE      | book  | ref  | idx_atb       | idx_atb | 4       | const |    2 | Using where; Using index |
	+----+-------------+-------+------+---------------+---------+---------+-------+------+--------------------------+

	-- Summary :
		a. Best prefix , Keep the consistency of index definition and usage order 
		b. Indexes need to be optimized step by step 
		c. Will contain In The scope of inquiry   Put it in where At the end of the term , Prevent failure .

	 In this case, there are Using where( Need to go back to the original table ); Using index( You don't need to go back to the original table ):
		 reason :  stay where authorid=1 and  typeid in(2,3) in authorid In the index (authorid,typeid,bid) in , Therefore, there is no need to go back to the original table ( You can find... Directly in the index table );
			   and typeid Although also in the index (authorid,typeid,bid) in , But with in The range query has made the typeid Index failure , So it's equivalent to no typeid This index , So you need to go back to the original table (using where);

	 For example, there is no In, Will not appear using where
	explain select bid from book where  authorid=1 and  typeid =3 order by typeid desc ;
	+----+-------------+-------+------+---------------+---------+---------+-------------+------+-------------+
	| id | select_type | table | type | possible_keys | key     | key_len | ref         | rows | Extra       |
	+----+-------------+-------+------+---------------+---------+---------+-------------+------+-------------+
	|  1 | SIMPLE      | book  | ref  | idx_atb       | idx_atb | 8       | const,const |    1 | Using index |
	+----+-------------+-------+------+---------------+---------+---------+-------------+------+-------------+

	 You can also use key_len prove In Can invalidate the index .

(2) Two table optimization 
	create table teacher2(
		tid int(4) primary key,
		cid int(4) not null
	);

	insert into teacher2 values(1,2);
	insert into teacher2 values(2,1);
	insert into teacher2 values(3,3);

	create table course2(
		cid int(4) ,
		cname varchar(20)
	);

	insert into course2 values(1,'java');
	insert into course2 values(2,'python');
	insert into course2 values(3,'kotlin');
	commit;

	 Left connection :
		explain select *from teacher2 t left outer join course2 c on t.cid=c.cid where c.cname='java';
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
		| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
		|  1 | SIMPLE      | t     | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                |
		|  1 | SIMPLE      | c     | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using join buffer |
		+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+

		 Which table does the index add ?		- Small tables drive large tables 
							- Indexes are built on frequently used fields ( This topic  t.cid=c.cid You know ,t.cid Fields are frequently used , So give this field a reference ) [ In general, for the left outer connection , Quote to the left table : Right connection , Quote... To the right watch ]
		 Watch :10 Data 
		 The big table :300 Data 
		where    Watch .x 10 =  The big table .y 300;  -- Circulated 10 Time 
			     The big table .y 300 =  Watch .x 10;	 -- Circulated 300 Time 

		select ...where  Watch .x10= The big table .x300 ;
		for(int i=0;i< Watch .length10;i++){
			for(int j=0;j< The big table .length300;j++){
				...
			}
		}

		select ...where  The big table .x300= Watch .x10 ;
		for(int i=0;i< The big table .length300;i++){
			for(int j=0;j< Watch .length10;j++){
				...
			}
		}

	-- above 2 individual FOR loop , Eventually it will cycle 3000 Time ; however   For a two-layer cycle : General advice   Loop the data small   Put the outer layer ; Large data loops are stored in memory .

	-- When writing  ..on t.cid=c.cid  when , Put the table with small amount of data   To the left ( Suppose this time t The table has a small amount of data )
	alter table teacher2 add index index_teacher2_cid(cid) ;
	explain select * from teacher2 t left outer join course2 c on t.cid=c.cid where c.cname='java';
	+----+-------------+-------+-------+--------------------+--------------------+---------+------+------+--------------------------------+
	| id | select_type | table | type  | possible_keys      | key                | key_len | ref  | rows | Extra                          |
	+----+-------------+-------+-------+--------------------+--------------------+---------+------+------+--------------------------------+
	|  1 | SIMPLE      | t     | index | index_teacher2_cid | index_teacher2_cid | 4       | NULL |    3 | Using index                    |
	|  1 | SIMPLE      | c     | ALL   | NULL               | NULL               | NULL    | NULL |    3 | Using where; Using join buffer |
	+----+-------------+-------+-------+--------------------+--------------------+---------+------+------+--------------------------------+

	alter table course2 add index index_course2_cname(cname);
	explain select * from teacher2 t left outer join course2 c on t.cid=c.cid where c.cname='java';
	+----+-------------+-------+------+---------------------+---------------------+---------+------------+------+-------------+
	| id | select_type | table | type | possible_keys       | key                 | key_len | ref        | rows | Extra       |
	+----+-------------+-------+------+---------------------+---------------------+---------+------------+------+-------------+
	|  1 | SIMPLE      | c     | ref  | index_course2_cname | index_course2_cname | 63      | const      |    1 | Using where |
	|  1 | SIMPLE      | t     | ref  | index_teacher2_cid  | index_teacher2_cid  | 4       | mydb.c.cid |    1 | Using index |
	+----+-------------+-------+------+---------------------+---------------------+---------+------------+------+-------------+

(3) Three tables optimize A B C
	a. Small tables drive large tables   b. The index is based on frequently queried fields 

7. Some principles for avoiding index failures

(1) Composite index 
    a. Composite index , Do not use across columns or out of order ( Best left prefix )
    b. Composite index , Try to use full index matching 
    
(2) Do not do anything on the index ( Calculation 、 function 、 Type conversion ), Otherwise, the index will fail 
    select ..where A.x = .. ;  -- hypothesis A.x It's the index 
     Don't :select ..where A.x*3 = .. ;
    
    explain select * from book where authorid = 1 and typeid = 2 ;-- Yes at 2 An index 
    +----+-------------+-------+------+---------------+---------+---------+-------------+------+-------+
    | id | select_type | table | type | possible_keys | key     | key_len | ref         | rows | Extra |
    +----+-------------+-------+------+---------------+---------+---------+-------------+------+-------+
    |  1 | SIMPLE      | book  | ref  | idx_atb       | idx_atb | 8       | const,const |    1 |       |
    +----+-------------+-------+------+---------------+---------+---------+-------------+------+-------+
    
    explain select * from book where authorid = 1 and typeid*2 = 2 ;-- Yes a 1 An index 
    +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
    | id | select_type | table | type | possible_keys | key     | key_len | ref   | rows | Extra       |
    +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
    |  1 | SIMPLE      | book  | ref  | idx_atb       | idx_atb | 4       | const |    1 | Using where |
    +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
    
    explain select * from book where authorid*2 = 1 and typeid*2 = 2 ;---- Yes 0 An index 
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    |  1 | SIMPLE      | book  | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    explain select * from book where authorid*2 = 1 and typeid = 2 ;---- Yes 0 An index , reason : For composite indexes , If the left side fails , The right side all fails .(a,b,c), For example, if  b invalid , be b c Simultaneous failure .
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
    |  1 | SIMPLE      | book  | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
    +----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	drop index idx_atb on book ;
	alter table book add index idx_authroid (authorid) ;
	alter table book add index idx_typeid (typeid) ;
	
	explain select * from book where authorid*2 = 1 and typeid = 2 ;
		+----+-------------+-------+------+---------------+------------+---------+-------+------+-------------+
		| id | select_type | table | type | possible_keys | key        | key_len | ref   | rows | Extra       |
		+----+-------------+-------+------+---------------+------------+---------+-------+------+-------------+
		|  1 | SIMPLE      | book  | ref  | idx_typeid    | idx_typeid | 4       | const |    2 | Using where |
		+----+-------------+-------+------+---------------+------------+---------+-------+------+-------------+

(3) A composite index cannot be used without equal (!=  <>) or is null (is not null), Otherwise, it and all the right side will be invalid .
	  If there is >, Then the index on itself and the right side are all invalid .

	explain select * from book where authorid = 1 and typeid =2 ;
    +----+-------------+-------+------+-------------------------+--------------+---------+-------+------+-------------+
    | id | select_type | table | type | possible_keys           | key          | key_len | ref   | rows | Extra       |
    +----+-------------+-------+------+-------------------------+--------------+---------+-------+------+-------------+
    |  1 | SIMPLE      | book  | ref  | idx_authroid,idx_typeid | idx_authroid | 4       | const |    1 | Using where |
    +----+-------------+-------+------+-------------------------+--------------+---------+-------+------+-------------+
    -- SQL Optimize , It's a probabilistic optimization . As to whether our optimization is actually used , Need to pass through explain speculate .

	explain select * from book where authorid != 1 and typeid =2 ;
    +----+-------------+-------+------+-------------------------+------------+---------+-------+------+-------------+
    | id | select_type | table | type | possible_keys           | key        | key_len | ref   | rows | Extra       |
    +----+-------------+-------+------+-------------------------+------------+---------+-------+------+-------------+
    |  1 | SIMPLE      | book  | ref  | idx_authroid,idx_typeid | idx_typeid | 4       | const |    2 | Using where |
    +----+-------------+-------+------+-------------------------+------------+---------+-------+------+-------------+
	
	explain select * from book where authorid != 1 and typeid !=2 ;
    +----+-------------+-------+------+-------------------------+------+---------+------+------+-------------+
    | id | select_type | table | type | possible_keys           | key  | key_len | ref  | rows | Extra       |
    +----+-------------+-------+------+-------------------------+------+---------+------+------+-------------+
    |  1 | SIMPLE      | book  | ALL  | idx_authroid,idx_typeid | NULL | NULL    | NULL |    4 | Using where |
    +----+-------------+-------+------+-------------------------+------+---------+------+------+-------------+

	 Experience probability situation (< > =): The reason is that there are SQL Optimizer , May affect our optimization .
	drop index idx_typeid on book;
	drop index idx_authroid on book;
	alter table book add index idx_book_at (authorid,typeid);
	explain select * from book where authorid = 1 and typeid =2 ;-- Composite index at All use 
		+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
		| id | select_type | table | type | possible_keys | key         | key_len | ref         | rows | Extra |
		+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
		|  1 | SIMPLE      | book  | ref  | idx_book_at   | idx_book_at | 8       | const,const |    1 |       |
		+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
	explain select * from book where authorid > 1 and typeid =2 ; -- If there is >, Then the index on itself and the right side are all invalid .
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
		| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
		|  1 | SIMPLE      | book  | ALL  | idx_book_at   | NULL | NULL    | NULL |    4 | Using where |
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
	explain select * from book where authorid = 1 and typeid >2 ;-- Composite index at All use 
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
		| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra       |
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
		|  1 | SIMPLE      | book  | range | idx_book_at   | idx_book_at | 8       | NULL |    1 | Using where |
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
	
	---- The obvious question of probability ---
	explain select * from book where authorid < 1 and typeid =2 ;-- Composite index at It's only used. 1 An index 
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
		| id | select_type | table | type  | possible_keys | key         | key_len | ref  | rows | Extra       |
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
		|  1 | SIMPLE      | book  | range | idx_book_at   | idx_book_at | 4       | NULL |    1 | Using where |
		+----+-------------+-------+-------+---------------+-------------+---------+------+------+-------------+
	
	explain select * from book where authorid < 4 and typeid =2 ;-- Composite indexes are all invalid 
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
		| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
		|  1 | SIMPLE      | book  | ALL  | idx_book_at   | NULL | NULL    | NULL |    4 | Using where |
		+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

	-- We learn index optimization  , Is a conclusion that applies in most cases , But because of SQL Optimizer and so on    The conclusion is not 100% correct .
	-- generally speaking ,  Range queries (> <  in), After the index failure .

(4) Remedy . Try to use index overlay (using index)
		(a,b,c)-- Composite index 
	select a,b,c from xx..where a=  .. and b =.. ;

(5) like Try to use “ Constant ” start , Do not use '%' start , Otherwise, the index will fail 
	select * from xx where name like '%x%' ; --name Index failure 

	explain select * from teacher  where tname like '%x%'; --tname Index failure 
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
		| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
		|  1 | SIMPLE      | teacher | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+

	explain select * from teacher  where tname like 'x%';
		+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+
		| id | select_type | table   | type  | possible_keys | key        | key_len | ref  | rows | Extra       |
		+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+
		|  1 | SIMPLE      | teacher | range | index_name    | index_name | 63      | NULL |    1 | Using where |
		+----+-------------+---------+-------+---------------+------------+---------+------+------+-------------+

	explain select tname from teacher  where tname like '%x%'; -- If you have to use like '%x%' Fuzzy query , You can use index overlay   Save some .
		+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+
		| id | select_type | table   | type  | possible_keys | key        | key_len | ref  | rows | Extra                    |
		+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+
		|  1 | SIMPLE      | teacher | index | NULL          | index_name | 63      | NULL |    4 | Using where; Using index |
		+----+-------------+---------+-------+---------------+------------+---------+------+------+--------------------------+

(6) Try not to use type conversion ( Show 、 Implicit ), Otherwise, the index will fail 
	explain select * from teacher where tname = 'abc' ;
		+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+
		| id | select_type | table   | type | possible_keys | key        | key_len | ref   | rows | Extra       |
		+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+
		|  1 | SIMPLE      | teacher | ref  | index_name    | index_name | 63      | const |    1 | Using where |
		+----+-------------+---------+------+---------------+------------+---------+-------+------+-------------+
	explain select * from teacher where tname = 123 ;// The bottom layer of the program will  123 -> '123', That is, type conversion is performed , So the index fails 
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
		| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
		|  1 | SIMPLE      | teacher | ALL  | index_name    | NULL | NULL    | NULL |    4 | Using where |
		+----+-------------+---------+------+---------------+------+---------+------+------+-------------+

(7) Try not to use or, Otherwise, the index will fail 
	explain select * from teacher where tname ='' and tcid >1 ;
		+----+-------------+---------+------+--------------------+------------+---------+-------+------+-------------+
		| id | select_type | table   | type | possible_keys      | key        | key_len | ref   | rows | Extra       |
		+----+-------------+---------+------+--------------------+------------+---------+-------+------+-------------+
		|  1 | SIMPLE      | teacher | ref  | uk_tcid,index_name | index_name | 63      | const |    1 | Using where |
		+----+-------------+---------+------+--------------------+------------+---------+-------+------+-------------+
	explain select * from teacher where tname ='' or tcid >1 ; -- take or Left side tname  invalid .
		+----+-------------+---------+------+--------------------+------+---------+------+------+-------------+
		| id | select_type | table   | type | possible_keys      | key  | key_len | ref  | rows | Extra       |
		+----+-------------+---------+------+--------------------+------+---------+------+------+-------------+
		|  1 | SIMPLE      | teacher | ALL  | uk_tcid,index_name | NULL | NULL    | NULL |    4 | Using where |
		+----+-------------+---------+------+--------------------+------+---------+------+------+-------------+

8. Some other optimization methods

(1)exist and in
	select ..from table where exist ( Subquery ) ;
	select ..from table where  Field  in  ( Subquery ) ;
	
	 If the data set of the main query is large , Then use In   , Efficient .
	 If the data set of subquery is large , Then use exist, Efficient .

	exist grammar : The result of the main query , Put it into the sub query result for condition verification ( See if the subquery has data , If there's data   Then the verification is successful )  ,
			    If the compound check , Keep the data ;

		select tname from teacher where exists (select * from teacher) ;
		-- Equivalent to select tname from teacher

		select tname from teacher where exists (select * from teacher where tid =9999) ;

	in:
		select ..from table where tid in  (1,3,5) ;

(2)order by  Optimize 
	using filesort  There are two algorithms : Two way sorting 、 One way sorting  ( according to IO The number of times )
	MySQL4.1 Before   By default   Two way sorting ; dual : scanning 2 Secondary disk 
		1: Read sort field from disk  , Sort the sort fields ( stay buffer Sorting in )   
		2: Scan other fields  
		
	--IO Higher consumption performance 
	MySQL4.1 after   By default   One way sorting  :  Read only once ( All fields ), stay buffer In order .  But one-way sorting will have some hidden dangers ( It doesn't have to be “ Single way |1 Time IO”, There may be many times IO).  reason : If the amount of data is very large , You can't   The data of all fields   Read at one time , therefore   Will be carried out in “ Fragment reading 、 Multiple read ”.
   
     Be careful : One way sorting is better than two-way sorting   It will take up more buffer.
    	 When using one-way sorting , If the data is large , You can consider increasing buffer Capacity size of :  set max_length_for_sort_data = 1024   Company byte

	 If max_length_for_sort_data It's too low , be mysql Automatically from   Single way -> dual    ( Too low : The total size of the columns to be sorted exceeds max_length_for_sort_data Number of bytes defined )

 Improve order by Query strategy :
    a. Choose to use one way 、 dual  ; adjustment buffer Capacity size of ;
    b. avoid select * ...
    c. Composite index   Do not use across columns  , avoid using filesort
    d. Ensure that all sorting fields   Consistency of sorting ( It's all in ascending order   or   Descending )

9.SQL screening

Slow query log :MySQL A type of logging provided , Used to record MySQL A response time that exceeds the threshold SQL sentence (long_query_time, Default 10 second )
Slow query log is off by default ; Suggest : Development tuning is open , and Close on final deployment .

 Check whether the slow query log is enabled  :
	show variables like '%slow_query_log%' ;

 The temporary setting is on :( When the service is turned off, it turns off by default )
    set global slow_query_log = 1 ;  -- Turn on in memory 
    exit
    service mysql restart

 Permanent setting on :
    /etc/my.cnf  Add configuration in :
    vi /etc/my.cnf
    [mysqld]
    slow_query_log=1
    slow_query_log_file=/var/lib/mysql/localhost-slow.log

 Check the slow query threshold :
	show variables like '%long_query_time%' ;

	 Temporarily set the threshold :
		set global long_query_time = 5 ; -- After setting up , It takes effect after re login  ( No need to restart the service )

	 Permanently set the threshold :
		/etc/my.cnf  Add configuration in :
		vi /etc/my.cnf
		[mysqld]
		long_query_time=3

    select sleep(4);
    select sleep(5);
    select sleep(3);
    select sleep(3);
    -- Query for..., which exceeds the threshold SQL:  show global status like '%slow_queries%' ;

(1) Slow query sql It was recorded in the Journal , Therefore, you can check the specific slowness through the log SQL.
	cat /var/lib/mysql/localhost-slow.log

(2) adopt mysqldumpslow Tool view slow SQL, You can pass some filter conditions   Quickly check to find out what needs to be located SQL
	mysqldumpslow --help
	s: sort order 
	r: The reverse 
	l: Lock time 
	g: Regular match pattern 
	
	
	-- Get the number of returned records 3 individual SQL
		mysqldumpslow -s r -t 3  /var/lib/mysql/localhost-slow.log

	-- Get the most visited 3 individual SQL
		mysqldumpslow -s c -t 3 /var/lib/mysql/localhost-slow.log

	-- Sort by time , front 10 Item contains left join Query statement SQL
		mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/localhost-slow.log

	 grammar :
		mysqldumpslow  Various parameters    Slow query log files 

10. Analyzing massive data

a. Simulate massive data    stored procedure ( nothing return)/ Storage function ( Yes return)
	create database testdata ;
	use testdata

	create table dept(
		dno int(5) primary key default 0,
		dname varchar(20) not null default '',
		loc varchar(30) default ''
	)engine=innodb default charset=utf8;

	create table emp(
		eid int(5) primary key,
		ename varchar(20) not null default '',
		job varchar(20) not null default '',
		deptno int(5) not null default 0
	)engine=innodb default charset=utf8;

	 By storing functions   Insert massive data :
	-- establish ( Employee name ) Storage function :
	randstring(6)  ->aXiayx   Used to simulate employee name 

	delimiter $  																							# Tell your program "$" Is a terminator ,";" Not as a terminator 
	create function randstring(n int)   returns varchar(255)												# Create a randstring function , Parameter is int, Returns a variable length string 
	begin 																									# Function start position ( amount to Java Medium "{}" Curly braces )
		declare  all_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ;		# Define a for storing all characters all_str The variable length is 100, The default values are those strings 
		declare return_str varchar(255) default '' ;														# Define a maximum length that can be returned as 255 String , The return value is empty by default 
		declare i int default 0 ;																			# Define a plastic i Variable is used to traverse the value passed in ( cycles )
		while i<n																							#while loop , from i Start and end with the value passed in 
		do  																								#while Loop start 
			set return_str = concat( return_str, substring(all_str, FLOOR(1+rand()*52) ,1) );  				# stay all_str Randomly generate a character splicing in return_str in ; concat: String concatenation ,substring: Intercepting string ,rand produce 0-1 The random number (MySQL Subscript from 1 Start counting ),FLOOR: Take the next integer of a number 
			set i=i+1 ;  																					# Add one to the subscript 
		end while ;	  																						#while The loop ends 
		return return_str;  																				# Returns a randomly generated string 
	end $   																								# Function end position 

	-- If you make a mistake :You have an error in your SQL syntax, explain SQL There is a mistake in the sentence syntax , Need modification SQL sentence ;
	-- If you make a mistake This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
		 Because stored procedures / When creating the storage function, it conflicts with the previous slow query log 
		 Resolve conflicts :
			 To settle temporarily (  Turn on log_bin_trust_function_creators )
				show variables like '%log_bin_trust_function_creators%';
				set global log_bin_trust_function_creators = 1;
			 Permanent solution :
			/etc/my.cnf
			[mysqld]
			log_bin_trust_function_creators = 1

	-- Generate random integers 
	delimiter $ 								# Tell your program "$" Is a terminator ,";" Not as a terminator 
	create function ran_num() returns int(5)	# Create a ran_num function , The return value is a length of 5 Of int Count 
	begin										# Function start position 
		declare i int default 0;				# Define a int The default value of the variable is 0;
		set i =floor( rand()*100 ) ;			# Produce a 0-99 The random number , Assign a value to i
		return i ;								# return i
	end $										# Function end position 

	-- Insert massive amounts of data through stored procedures :emp In the table  , 10000, 100000
	delimiter $																			# Tell your program "$" Is a terminator ,";" Not as a terminator 
	create procedure insert_emp( in eid_start int(10),in data_times int(10))			# Create a insert_emp stored procedure , Pass in parameters of two input types ,eid_start Is the position to start inserting ,data_times Is the number of pieces of data 
	begin 																				# The starting position of the stored procedure 
		declare i int default 0;														# Define a int Variable i The default value is 0
		set autocommit = 0 ;															# Set auto submit off ( Avoid inserting submit once , Submit once inserted )
		repeat																			#repeat Loop start 
			insert into emp values(eid_start + i, randstring(5) ,'other' ,ran_num()) ;	# stay emp Table insert data 
			set i=i+1 ;																	# Subscript plus one , Next data 
			until i=data_times															# The end of the loop (i Equal to the length that needs to be inserted to end the cycle )
		end repeat ;																	#repeat The loop ends 
		commit ;																		# Submit all data 
	end $																				# The starting position of the stored procedure 

	-- Insert massive amounts of data through stored procedures :dept In the table 
	delimiter $
	create procedure insert_dept(in dno_start int(10) ,in data_times int(10))
	begin
		declare i int default 0;
		set autocommit = 0 ;
		repeat
			insert into dept values(dno_start+i ,randstring(6),randstring(8)) ;
			set i=i+1 ;
			until i=data_times
		end repeat ;
		commit ;
	end $

	-- insert data 
	delimiter ; 					# Set up ";" Is the end of the program 
	call insert_emp(1000,800000) ;	# call insert_emp stored procedure , from 1000 Start , Insert 80 10000 employee data 
	call insert_dept(10,30) ;		# call insert_dept stored procedure , from 10 Start , Insert 30 Department data 


b. Analyzing massive data :
(1)profiles
	show profiles ; -- Off by default 
	show variables like '%profiling%';
	set profiling = on ;
	show profiles ;   Will record all profiling All after opening SQL Time spent on query statements . shortcoming :  Imprecise , You can only see the total time spent , You can't see the consumption time of each hardware (cpu  io)

(2) Precise analysis : sql The diagnosis 
	 show profile all for query  The query in the previous step Query_Id
	 show profile cpu,block io for query  The query in the previous step Query_Id

(3) Global query log  : Record... After opening   All SQL sentence . ( This global record operation   Just tuning 、 Just open it during the development process , In the final deployment implementation   Be sure to close )
	show variables like '%general_log%';

	-- Mode one : All that is done SQL Record in a table 
	set global general_log = 1 ;-- Open global log 
	set global log_output='table' ; -- Set up   It will be all SQL  Record in a table 

	-- Mode two : All that is done SQL Record it in a file 
	set global log_output='file' ;
	set global general_log = on ;
	set global general_log_file='/tmp/general.log' ;

	 After opening , Will record all SQL :  Will be recorded  mysql.general_log In the table .
		select * from  mysql.general_log ;

11. Locking mechanism

Solve the problem of resource sharing Concurrency problems caused by .
Example : Buy the last dress X
A: X buy : X Lock -> Try the clothes … Place an order … payment … pack ->X Unlock
B: X buy : Find out X Locked , wait for X Unlock , X Sold out

 classification :
 Operation type :
	a. Read the lock ( Shared lock ):  For the same data ( clothes ), Multiple read operations can be performed simultaneously , Mutual interference .
	b. Write lock ( The mutex ):  If the current write operation is not finished ( A series of operations for buying clothes ), You cannot perform other read operations 、 Write operations 

 Operating range :
	a. Table locks  : Lock the whole table at one time . Such as MyISAM The storage engine uses table locks , Low overhead 、 Locked fast ; No deadlock ; But the range of locks is large , Prone to lock conflicts 、 Low concurrency .
	b. Row lock  : Lock one piece of data at a time . Such as InnoDB The storage engine uses row locks , Spending big , Lock the slow ; It's easy to deadlock ; The range of the lock is small , Not prone to lock conflicts , High concurrency ( Very small probability   High concurrency problem : Dirty reading 、 Fantasy reading 、 Non repeatability 、 Problems such as missing updates ).
	c. Page locks 

Example :

(1) Table locks  :  -- Self increment operation  MYSQL/SQLSERVER  Support ;oracle It is necessary to realize self increment by means of sequence 
	create table tablelock
	(
	id int primary key auto_increment ,
	name varchar(20)
	)engine myisam;

	insert into tablelock(name) values('a1');
	insert into tablelock(name) values('a2');
	insert into tablelock(name) values('a3');
	insert into tablelock(name) values('a4');
	insert into tablelock(name) values('a5');
	commit;

	 Add lock :
	lock table  surface 1  read/write  , surface 2  read/write   ,...

	 Look at the locked table :
	show open tables ;

	 conversation :session : Every access to data dos Command line 、 Database client tool    It's all a conversation 

	=== Add read lock :
		 conversation 0:( Yes tablelock Lock the watch , visit )
			lock table  tablelock read ; -- to tablelock Add read lock 
			select * from tablelock; -- read ( check ), Sure 
			delete from tablelock where id =1 ; -- Write ( Additions and deletions ), Can not be 

			select * from dept ; -- read , Can not be 
			delete from dept where eid = 1; -- Write , Can not be 
			 Conclusion 1:
				-- If a session   Yes A The watch has been added read lock , be   The session   It can be done to A Table for reading operations 、 Unable to write ;  And   This session cannot read other tables 、 Write operations .
				-- That is, if you give A The watch is locked , The current session can only A Table for reading operations .

		 conversation 1( Other conversations ):( visit tablelock Lock the watch )
			select * from tablelock;   -- read ( check ), Sure 
			delete from tablelock where id =1 ; -- Write , Meeting “ wait for ” conversation 0 Release the lock 
		 conversation 2( Other conversations ):( Access other unlocked tables )
			select * from dept ;  -- read ( check ), Sure 
			delete from dept where dno = 10; -- Write , Sure 
			 Conclusion 2:
			-- summary :
				 conversation 0 to A The watch is locked ; Operation of other sessions :a. Other tables can be (A A table other than a table ) Read 、 Write operations 
								b. Yes A surface : read - Sure ;   Write - Need to wait to release the lock .
		 Release the lock : unlock tables ;

	=== Add write lock :
		 conversation 0:
			lock table tablelock write ;

			 Current session ( conversation 0)  You can write to a locked table    Do anything ( Additions and deletions ); But you can't   operation ( Additions and deletions ) Other watches 
		 Other conversations :
			 To conversation 0 A table with a write lock in   The premise of adding, deleting, modifying and querying is : Wait for session 0 Release the write lock 

	MySQL Lock mode of watch level lock 
		MyISAM In the execution of the query statement (SELECT) front , Will automatically lock all tables involved ,
		 Is performing an update operation (DML) front , Will automatically lock the tables involved .
		 So for MyISAM Table operation , There will be the following :
			a、 Yes MyISAM Read operation of table ( Add read lock ), Will not block other processes ( conversation ) Read requests to the same table ,
				 But it blocks write requests to the same table . Only when the read lock is released , To perform other process write operations .
			b、 Yes MyISAM Write operation of table ( Add write lock ), Will block other processes ( conversation ) Read and write operations on the same table ,
				 Only when the write lock is released , Will perform read and write operations of other processes .

	 Analysis table locking :
		 See which tables are locked :   show open tables ;  1 Represents being locked 
		 Analyze the severity of table locking : show status like 'table%' ;
				Table_locks_immediate : That is, the number of locks that may be obtained 
				Table_locks_waited: Number of table locks to wait ( If the value is larger , It indicates that the greater the lock competition )
		 General advice :
			Table_locks_immediate/Table_locks_waited > 5000,  The proposal USES InnoDB engine , otherwise MyISAM engine 


(2) Row table (InnoDB)
	create table linelock(
		id int(5) primary key auto_increment,
		name varchar(20)
	)engine=innodb ;
	insert into linelock(name) values('1')  ;
	insert into linelock(name) values('2')  ;
	insert into linelock(name) values('3')  ;
	insert into linelock(name) values('4')  ;
	insert into linelock(name) values('5')  ;

	--mysql Default Auto commit;	oracle Default does not automatically commit ;

	 To study row locks , For the time being, it will automatically commit close ;  set autocommit =0 ;  You need to pass commit

	 Row lock , Operate on the same data :
		 conversation 0:  Write operations 
			insert into linelock values('a6') ;
		 conversation 1:  Write operations   The same data 
			update linelock set name='ax' where id = 6;
		 Row lock :
			1. If the session x For a piece of data a Conduct  DML operation ( When studying : Automatic... Is turned off commit Under the circumstances ), Then other sessions must wait for session x End the business (commit/rollback) after    To access the data a To operate .
			2. Table locks   It's through unlock tables, You can also unlock... Through transactions  ;  Row lock   Is unlocked through transactions .

	 Row lock , Working with different data :
		 conversation 0:  Write operations 
			insert into linelock values(8,'a8') ;
		 conversation 1:  Write operations ,  Different data 
			update linelock set name='ax' where id = 5;
			 Row lock , Lock one row of data at a time ; therefore   If you operate on different data , It does not interfere with .

	 Precautions for row lock :
	a. If there is no index , The row lock will be turned into a table lock 
		show index from linelock ;
		alter table linelock add index idx_linelock_name(name);

		 conversation 0:  Write operations 
			update linelock set name = 'ai' where name = '3' ;
		 conversation 1:  Write operations ,  Different data 
			update linelock set name = 'aiX' where name = '4' ;

		 conversation 0:  Write operations 
			update linelock set name = 'ai' where name = 3 ;
		 conversation 1:  Write operations ,  Different data 
			update linelock set name = 'aiX' where name = 4 ;

		-- You can find , The data is blocked ( Lock )
		--  reason : If the index class   There was a type conversion , The index becomes invalid .  therefore   This operation , Will lock from the row   Turn to table lock .

	b. A special case of row lock : Clearance lock : The value is in the range , But it doesn't exist 
		-- here linelock In the table   No, id=7 The data of 
		update linelock set name ='x' where id >1 and id<9 ;   -- Here where In the range , No, id=7 The data of , be id=7 The data becomes gap .
		 The gap :Mysql Will automatically give   The gap   Caucasus  -> Clearance lock . namely   This topic   Will automatically give id=7 Data plus   Clearance lock ( Row lock ).
		 Row lock : If there is where, Then the actual range   Namely where Range after ( Not the actual value )

	 How to just query data , Can you lock it ?  Sure    for update
	 When studying , Will automatically submit closed :
		set autocommit =0 ;
		start transaction ;
		begin ;
	select * from linelock where id =2 for update ;

	 adopt for update Yes query Statement to lock .

	 Row lock :
	InnoDB Row lock is used by default ;
	 shortcoming :  Greater loss of performance than watch lock .
	 advantage : Strong concurrency , Efficient .
	 So I suggest , High concurrency InnoDB, Otherwise, use MyISAM.

	 Line lock analysis :
	  show status like '%innodb_row_lock%' ;
		 Innodb_row_lock_current_waits : The number of locks currently waiting 
		 Innodb_row_lock_time: The total waiting time . From system startup to now   The total waiting time 
		 Innodb_row_lock_time_avg  : Average waiting time . Average waiting time from system startup to now 
		 Innodb_row_lock_time_max  : Maximum waiting time . Maximum waiting time from system startup to now 
		 Innodb_row_lock_waits :	 Number of waits . The total number of times to wait since the system was started 

12. Master slave copy

An implementation of cluster in database
windows:mysql Lord
linux:mysql from

 install windows edition mysql:
	 If you have installed Mysql, To reinstall    You need to : To uninstall first   Install again 
	 To uninstall first :
		 Uninstall through the computer's own uninstall tool Mysql ( Computer housekeeper can also )
		 Delete one mysql Cache file C:\ProgramData\MySQL
		 Delete registry regedit All in mysql Related configuration 
		-- Restart the computer 

	 install MYSQL:
		 When installing , If there is no response :   Then reopen D:\MySQL\MySQL Server 5.5\bin\MySQLInstanceConfig.exe

	 Graphical client : SQLyog, Navicat

	 If you want to connect to the database remotely , You need to authorize remote access .
	 Authorize remote access  :(A->B, Then B The computer Mysql Execute the following command in )
	GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
	FLUSH PRIVILEGES;

	 If you still report an error : Maybe the firewall is not closed  :   stay B Turn off firewall   service iptables stop

 Realize master-slave synchronization ( Master slave copy ): chart 
	1.master The number that will change   Local   Binary log (binary log) ; This process   be called : Binary log is one thing 
	2.slave take master Of binary log Copy to your own  relay log( Relay log file ) in 
	3. Relay log events , Read the data into your own database 
MYSQL Master slave copy   It's asynchronous , Serial ,  There is a delay 

master:slave = 1:n

 To configure :
windows(mysql: my.ini)
  linux(mysql: my.cnf)

 Before configuration , In order to be correct , Set the permission first ( The remote access )、 Firewall, etc :
	 close windows/linux A firewall : windows: Right click “ The Internet ”   ,linux: service iptables stop
	Mysql Allow remote connections (windowos/linux):
		GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
		FLUSH PRIVILEGES;


 host ( The following code and operation   All on the host windows In the operation ):
my.ini
[mysqld]
#id
server-id=1
# Binary log file ( Note that /   No \)
log-bin="D:/MySQL/MySQL Server 5.5/data/mysql-bin"
# Error log file 
log-error="D:/MySQL/MySQL Server 5.5/data/mysql-error"
# Master slave synchronization   Ignored database 
binlog-ignore-db=mysql
#( Optional ) When specifying master-slave synchronization , Which databases are synchronized 
binlog-do-db=test

windows Database in   Which computer is authorized for the database   It's your own from the database :
 GRANT REPLICATION slave,reload,super ON *.* TO 'root'@'192.168.2.%' IDENTIFIED BY 'root';
 flush privileges ;

 View the status of the master database ( Every time before the left master-slave synchronization , Need to observe   The latest value of the host state )
	show master status;  (mysql-bin.000001、 107)

 Slave ( The following code and operation   All in slave linux In the operation ):

my.cnf
[mysqld]
server-id=2
log-bin=mysql-bin
replicate-do-db=test

linux Data in   Which CNC computer is authorized   It's your own host computer 
CHANGE MASTER TO
MASTER_HOST = '192.168.2.2',
MASTER_USER = 'root',
MASTER_PASSWORD = 'root',
MASTER_PORT = 3306,
master_log_file='mysql-bin.000001',
master_log_pos=107;
	 If you make a mistake :This operation cannot be performed with a running slave; run STOP SLAVE first
	 solve :STOP SLAVE ; Execute the authorization statement again 

 Turn on master-slave synchronization :
	 Slave linux:
	start slave ;
	 test   show slave status \G	 Main observation : Slave_IO_Running and  Slave_SQL_Running, Make sure both are yes; If not all yes, Look at the... Below  Last_IO_Error.
 This time   adopt  Last_IO_Error The reason for finding the error is   The master and slave use the same server-id,  Check : View in master and slave respectively serverid:  show variables like 'server_id' ;
	 You can find , stay Linux Medium my.cnf Set up in server-id=2, But in practice   exactly server-id=1, reason : May be  linux edition Mysql One of the bug, It could be  windows and Linux Compatibility problems caused by inconsistent versions .
	 Solve and change bug: set global server_id =2 ;

	stop slave ;
	 set global server_id =2 ;
	start slave ;
	 show slave status \G

	 demonstration :
	 Lord windows => from liunx
	windows:
	 Will table , insert data 
	 Observe the data of the table from the database 
原网站

版权声明
本文为[Please Sit Down]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202130629581615.html