当前位置:网站首页>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
边栏推荐
猜你喜欢
Category of IP address
最长上升子序列模型 AcWing 1017. 怪盗基德的滑翔翼
Synchronized underlying principle, volatile keyword analysis
Led analog and digital dimming
JS operation
Upload an e-office V9 arbitrary file [vulnerability recurrence practice]
H3C VXLAN配置
Oracle makes it clear at one time that a field with multiple separators will be split into multiple rows, and then multiple rows and columns. Multiple separators will be split into multiple rows, and
opencv之图像分割
【istio简介、架构、组件】
随机推荐
Why choose cloud native database
LED模拟与数字调光
Output all composite numbers between 6 and 1000
硬件大熊原创合集(2022/06更新)
Test pits - what test points should be paid attention to when adding fields to existing interfaces (or database tables)?
OpenGL frame buffer
MySQL主从延迟的解决方案
Common operating commands of Linux
年薪50w阿里P8亲自下场,教你如何从测试进阶
Analysis of abnormal channel number information before and after AGC re signature service
Redis summary
Several methods of calculating the average value of two numbers
面板显示技术:LCD与OLED
Greenplum 6.x build_ Environment configuration
硬件大熊原创合集(2022/05更新)
Personal deduction topic classification record
selenium自动化集成,八年测试经验软测工程师,一篇文章带你学懂
Opencv converts 16 bit image data to 8 bits and 8 to 16
About using CDN based on Kangle and EP panel
[step on the pit] Nacos registration has been connected to localhost:8848, no available server