ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Mysql高级

2020-03-17 19:56:35  阅读:197  来源: 互联网

标签:高级 查询 索引 Mysql null where id select


  1 mysql高级
  2     ”练武不练功,到老一场空,认认真真练一遍,今天多学一门技术,明天少说一句求人的话;高新12k以上的岗位一定会靠你sql“
  3     “DBA每天做索引重建工作,锁表重建索引”
  4     “物理删除改为逻辑删除,其一,大数据时代保留数据,以便分析;其二,为了索引”
  5     “运维问题,数据说话,理工类工作严禁我觉得”
  6     “程序员分两种:15k以下的只能完成功能;撑死优秀完成功能15-20;20以上的不但能完成功能也能搞定性能”
  7     
  8     1、mysql的架构介绍 
  9         1.1Mysql简介
 10             1.1.1概述
 11                 
 12             1.1.2高级Mysql(完整的mysql优化需要很深的功底,大公司甚至有专门的DBA写上述)
 13                 1.1.2.1mysql内核
 14                 1.1.3sql优化工程师
 15                 1.1.4mysql服务器优化
 16                 1.1.5各种参数常量设定
 17                 1.1.6查询语句优化
 18                 1.1.7主从复制
 19                 1.1.8软硬件升级
 20                 1.1.9容灾备份
 21                 1.1.10sql编程
 22             
 23         1.2Mysqllinux版安装
 24             1.2.1 mysql5.5rpm
 25                 1.2.1.1 下载地址
 26                     http://dev.mysql.com/downloads/mysql/,下载ga版
 27                 1.2.1.2 检查当前系统是否安装过mysql
 28                     rpm -qa|grep -i mysql
 29                 1.2.1.3 安装mysql服务端(注意提示)
 30                     cd /opt (linux尽量不含中文不含空格)
 31                     rpm -ivh MySQL-server-5.5.48-1.linux2.6.i386.rpm
 32                     注意修改密码
 33                 1.2.1.4 安装mysql客户端
 34                     rpm -ivh MySQL-client-5.5.48-1.linux2.6.i386.rpm
 35                 1.2.1.5 查看mysql安装时创建的mysql用户和mysql组
 36                     ps -ef|grep mysql
 37                     cat /etc/passwd |grep mysql
 38                     cat /etc/group |grep mysql
 39                     mysqladmin --version
 40                 1.2.1.6 mysql服务的启+停
 41                     service mysql start|stop|restart   
 42                     ps -ef|grep mysql
 43                     top 可以从服务器启动持续时间一定判断该公司研发部的水准,经常关的要注意
 44                 1.2.1.7 mysql服务启动后,开始连接
 45                     /usr/bin/mysqladmin -u root password 123456
 46                     首次连接成功
 47                     注意这里,因为Mysql默认没有密码,所以这里我们没有输入密码就直接连上了
 48                     按照安装server中的提示修改登录密码
 49                 1.2.1.8 自启动mysql服务
 50                     chkconfig mysql on
 51                     chkconfig --list | grep mysql
 52                     cat  /etc/inittab inittab is no longer used when using systemd.
 53                     ntsysv 图形显示开机启动
 54                 1.2.1.9 修改配置文件位置
 55                     cd /usr/share/mysql/
 56                     cp my-huge.cnf /etc/my.cnf
 57                 1.2.1.10 修改字符集合数据存储路径
 58                     show variables like 'character%';
 59                     show variables like '%char%';
 60                     默认客户端和服务器都用了latin1所以会乱码。5.7是character_set_server=utf8一个,和5.5有区别
 61                     在字符集修改之前创建的库没有收到配置文件影响,最好安装mysql之后立即修改字符集
 62                 1.2.1.11 mysql的安装位置                  
 63                     在linux下查看安装目录 ps -ef | grep mysql
 64                     /var/lib/mysql #数据库文件的存放位置
 65                     /usr/share/mysql  #主管配置文件的目录
 66                     /usr/bin    #相关命令
 67                     /etc/init.d/mysql #启停脚本相关
 68                
 69         1.3Mysql配置文件
 70             主要配置文件:
 71             1.3.1 二进制日志log-bin
 72                 主要用于主从复制
 73             1.3.2 错误日志log-error 
 74                 -默认是关闭的,记录严重的警告和错误信息,每次启动和关闭时候的详细信息
 75                 
 76             1.3.3 查询日志log
 77                 -默认是关闭的,记录查询的sql语句,如果开启会减低mysql的整体性能,因为记录日志也是消耗系统资源的
 78             1.3.4 数据文件
 79                 两系统
 80                     windows 
 81                         D:\devSoft\MySQLServer5.5\data目录下可以挑选很多库
 82                     linux
 83                         看看当前系统中的全部库后再进去   ls -lF|grep ^d
 84                         默认路径:/var/lib/mysql      
 85                 frm文件 
 86                     存放表结构
 87                 myd文件
 88                     存放表数据
 89                 myi 
 90                     存放索引表
 91                               
 92             1.3.5 如何配置
 93                 windows -my.ini文件
 94                     显示的配置:
 95                     log-bin=
 96                     log-error=
 97                 linux   -/etc/my.cnf文件
 98         1.4Mysql逻辑架构
 99             1.4.1总体概览
100                 ①连接层(jdbc,native c api)
101                 ②服务层 -业务逻辑处理层
102                 ③引擎层 -数据存储引擎 
103                 ④存储层 -文件存储层
104                 插件式的存储引擎设计将查询和其它的系统任务以及数据处理提取相分离
105                 
106             1.4.2查询说明
107         1.5Mysql存储引擎
108             1.5.1 查看命令
109                 show engines;#支持哪些存储引擎
110                 show variables like '%storage_engine%';#当前的存储引擎
111             1.5.2 MyISAM和InnoDB
112                 对比项     MyISAM                                                     InnoDB
113                 主外键     不支持                                                     支持
114                 事务       不支持                                                        支持
115                 行锁表     表锁,即使操作一条记录也会锁住整个表,不适合高并发操作     行锁,操作时只锁住某一行,不对其他行有影响,适合高并发
116                 缓存       只缓存索引,不缓存真实数据                                  不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性影响
117                 表空间     小                                                         大
118                 关注点     性能                                                       事务
119                 默认安装    Y                                                           Y
120             1.5.3 阿里巴巴、淘宝用哪个
121                 产品  价格  目标  主要功能    是否投入生产
122                 Percona Server 免费 提供XtraDB存储引擎的包装器和其他分析工具 XtrDB 是
123                 MariaDB     免费  
124                 Drizzle     免费
125     2、索引优化分析
126         2.1性能下降SQL慢、执行时间长,等待时间长
127             2.1.1查询语句写的烂
128             2.1.2索引失效
129                 单值索引
130                     select * from user where name='';create index idx_user_name on user(name);
131                 复合索引
132                     select * from user where name='' and email='';create index idx_user_nameEmail on user(name,email);
133             2.1.3关联查询太多join(设计缺陷或不得已的需求)
134                 
135             2.1.4服务器调优及各参数设置(缓冲、线程数等)
136             
137         2.2常见通用的join查询
138             2.2.1SQL执行顺序
139                 手写
140                 机读
141                 总结
142             2.2.2join图
143                 (画圆形图理解,直观)
144                 内连接(共有部分)        SELECT <select_list> FROM TableA A INNER JOIN TableB B ON A.Key = B.Key;
145                 左连接 (AB共有+A的独有) SELECT <select_list> FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key;
146                 右连接(AB共有+B的独有)  SELECT <select_list> FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key;
147                 左外链接(A独有)         SELECT <select_list> FROM TableA A LEFT JOIN TableB B ON A.Key = B.Key WHERE B.Key IS NULL;
148                 右外连接(B独有)         SELECT <select_list> FROM TableA A RIGHT JOIN TableB B ON A.Key = B.Key WHERE A.Key IS NULL;
149                 全连接(A+B)             SELECT <select_list> FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key; (mysql不支持)
150                 全外连接(独A+独B)       SELECT <select_list> FROM TableA A FULL OUTER JOIN TableB B ON A.Key = B.Key WHERE A.Key IS NULL OR B.Key IS NULL ;
151             2.2.3建表SQL
152                 creat database db0629;
153                 CREATE TABLE `tbl_dept`(
154                 `id` INT(11) NOT NULL AUTO_INCREMENT,
155                 `deptName` VARCHAR(30) DEFAULT NULL,
156                 `locAdd` VARCHAR(40) DEFAULT NULL,
157                 PRIMARY KEY(`id`)
158                 )ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
159                 
160                 CREATE TALBLE `tbl_emp`(
161                 `id` INT(11) NOT NULL AUTO_INCREMENT,
162                 `name` VARCHAR(20) DEFAULT NULL,
163                 `deptId` INT(11) DEFAULT NULL,
164                 PRIMARY KEY(`id`),
165                 KEY `fk_dept_id`(`deptId`)
166                 #CONSTRAINT `fk_dept_id` FOREIGN KEY(`deptId`) REFERENCES `tbl_dept`(`id`)
167                 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
168                 
169                 INSERT INTO tbl_dept(deptName,locAdd) VALUES('RD',11);
170                 INSERT INTO tbl_dept(deptName,locAdd) VALUES('HR',12);
171                 INSERT INTO tbl_dept(deptName,locAdd) VALUES('MK',13);
172                 INSERT INTO tbl_dept(deptName,locAdd) VALUES('MIS',14);
173                 INSERT INTO tbl_dept(deptName,locAdd) VALUES('FD',15);
174                 
175                 
176                 INSERT INTO tbl_emp(NAME,deptId) VALUES('z3',1);
177                 INSERT INTO tbl_emp(NAME,deptId) VALUES('z4',1);
178                 INSERT INTO tbl_emp(NAME,deptId) VALUES('z5',1);
179                 INSERT INTO tbl_emp(NAME,deptId) VALUES('w5',2);
180                 INSERT INTO tbl_emp(NAME,deptId) VALUES('w6',2);
181                 INSERT INTO tbl_emp(NAME,deptId) VALUES('s7',3);
182                 INSERT INTO tbl_emp(NAME,deptId) VALUES('s8',4);
183                 INSERT INTO tbl_emp(NAME,deptId) VALUES('s9',51);
184             2.2.4 7种JOIN
185                 全连接 
186                     select * from tbl_emp a left join tbl_dept b on a.deptId = b.id
187                     union
188                     select * from tb1_emp a right join tbl_dept b on a.deptId = b.id
189                 全外连接
190                     select * from tbl_emp a left join tbl_dept b on a.deptId = b.id where b.id is null;
191                     union
192                     select * from tb1_emp a right join tbl_dept b on a.deptId = b.id where a.deptId is null;
193         2.3索引简介
194             2.3.1 索引是什么
195                 MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构。
196                 可以得到索引的本质:索引是数据结构
197                     索引的目的在于提高效率,可以类比字典,
198                     如果要查询“mysql”这个单词,我们肯定需要定位m字母,然后从上往下找到y字母,再找到剩下的sql
199                     如果没有索引那么你可能需要a-z,如果我想找到java开头的单词呢:或者Oracle开头的单词呢?
200                     是不是觉得如果没有索引,这个事情根本无法完成?
201                 你可以简单理解为“排好序的快速查找数据结构” ☆
202                     在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构基础上实现高级查找算法,这种数据结构就是索引。
203 
204                 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上
205                 我们平常所说的索引,如果没有特别指明,都是值B树(多路搜索树,并不一定是二叉的)结构组织的索引。其中聚集索引,次要索引,覆盖索引
206                 符合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引,当然,除了B+这种类型的索引之外,还有哈希索引(hash
207                 index)等。
208             2.3.2 优势
209                 类似大学图书馆建书目索引,提高数据检索的效率,降低数据的io成本;
210                 通过索引列对数据进行排序,降低数据排序的成本,降低了cpu的消耗;
211             2.3.3 劣势
212                 ①实际上索引也是一张表,该表保存了主键和索引字段,并指向实体表的记录,所以索引列也是要占用空间的
213                 ②虽然索引大大提过了查找的速度,同事却会降低更新表的速度,如对表进行insert,update和delete。
214                     因为更新表时,Mysql不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,
215                     都会调整因为更新所带来的键值变化后的索引信息
216                 ③索引只是提高效率的一个因素,如果你的mysql有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询
217                 
218             2.3.4 mysql索引分类
219                 建议一张表的索引最多不要超过5个
220                 ①单值索引
221                     即一个索引只包含单个列,一个表可以有多个单列索引
222                 ②唯一索引
223                     索引列的值必须唯一,但允许为空值
224                 ③复合索引
225                     即一个所以不能包含过个列
226                 ④基本语法
227                     一、创建
228                         CREATE 【UNIQUE】 INDEX indexName ON mytable(columnname(length));
229                         ALTER mytable ADD 【UNIQUE】INDEX 【indexName】ON(columnname(length))
230                     二、删除
231                         DROP INDEX 【indexName】ON mytable;
232                     三、查看
233                         SHOW INDEX FROM table_name\G
234                     四、使用alter命令
235                         有四种方式添加数据表的索引
236                         ALTER TABLE tbl_name ADD PRIMARY KEY(column_list);该语句添加了一个主键,这意味着索引值必须是唯一的,且不能为NULL。
237                         ALTER TABLE tbl_name ADD UNIQUE index_name(column_list);这条语句创建的索引值必须是唯一的(除了NUll外,null可能出现多次)。
238                         ALTER TABLE tbl_name ADD INDEX index_name(column_list);添加普通索引,索引值可以出现多次。
239                         ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list);,该语句指定了索引为FULLTEXT,用于全文索引。
240                         
241             2.3.5 mysql索引结构
242                 2.3.5.1 BTree索引
243                     检索原理
244                         真实的数据存在于叶子节点,非叶子节点只 不存真实的数据项,只存储指引搜索方向的数据项
245                 2.3.5.2 Hash索引
246                 2.3.5.3 full-text全文索引
247                 2.3.5.4 R-Tree索引
248             2.3.6 哪些情况需要创建索引
249                 2.3.6.1 主键自动建立唯一索引
250                 2.3.6.2 频繁作为查询条件的字段应该创建索引
251                 2.3.6.3 查询中与其它表关联的字段,外键关系建立索引
252                 2.3.6.4 频繁更新的字段不适合创建索引
253                     - 因为每次更新不单单是更新了记录还会更新索引
254                 2.3.6.5 where条件里用不到的字段不创建索引
255                 2.3.6.6 单键/组合索引的选择问题,who?(在高并发下倾向创建组合索引)
256                 2.3.6.7 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
257                 2.3.6.8 查询中统计或者分组字段
258             2.3.7 哪些情况不需要创建索引
259                 2.3.7.1 表记录太少
260                 2.3.7.2 经常增删改的表
261                     why:提高了查询速度,同事却会降低了更新表的速度,如对表进行insert、update和delete。
262                     因为更新表时,Mysql不仅要保存数据,还要保存一下索引文件
263                 2.3.7.3 数据重复且平均的表自短发,因此应该只为最经常查询的和最经常排序的数据列建立索引。
264                         注意,如果某个数据列包含许多重复内容,为它建立索引就没有太大的实际效果
265                             索引的选择性是指索引列中不同值的数目与表中记录的数的比。如果一个表中有2000条记录,表索引列
266                             有1980个不通的值,那么这个索引的选择性就是1980/2000=0.99.一个索引的选择性越接近1,那么这个索引的效率就越高
267                             
268            
269         2.4性能分析 ☆
270             2.4.1 MySQL Query Optimizer
271                 2.4.1.1 Mysql中有专门负责优化select语句的优化器模块,主要功能:通过计算分析系统中收到的统计信息,为客户端请求的Query提供他认为最优的执行计划
272                 (他认为最优的数据检索方式,但不见得是DBA认为是最优的,这部分最耗时间)
273                 2.4.1.2 当客户端想Mysql请求一条Query,命令解析器模块完成请求分类,区别是SELECT并转发给Mysql Query Optimizer时,Mysql Query Optimizer首先会对整条query进行优化
274                 ,处理掉一些常量表达式的预算,直接换算成常量值,并对query中的条件进行简化和转换,如果去掉一些无用和显而易见条件,结构调整等。然后分析Query中的Hint信息(如果有)
275                 ,看现实Hint信息是否可以完全确定该query的执行计划,如果没有Hint或Hint信息还不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据query进行写相应的计算分析
276                 ,然后再得出最后的执行计划。
277                 
278             2.4.2 MySQL 常见瓶颈
279                 2.4.2.1 CPU:CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据的时候
280                 2.4.2.2 IO:磁盘I/O瓶颈发生在装入数据远大于内存容量的时候
281                 2.4.2.3 服务器硬件性能瓶颈:top,free,iostat和vmstat来查看系统的性能状态
282             
283             2.4.3 Explian
284                 2.4.3.1 是什么(查看执行计划)
285                     使用Explain关键字可以模拟优化器执行sql查询,从而知道mysql是
286                     如何处理你的sql语句。分析你的查询语句或是表结构的性能瓶颈
287                     官网介绍
288                         
289                 2.4.3.2 能干嘛
290                     2.4.3.2.1 表的读取顺序
291                     2.4.3.2.2 数据读取操作的操作类型
292                     2.4.3.2.3 哪些索引可以使用
293                     2.4.3.2.4 哪些索引被实际使用
294                     2.4.3.2.5 表之间的引用
295                     2.4.3.2.6 每张表有多少行被优化器查询
296                     
297                 2.4.3.3 怎么玩
298                     select * from tbl_emp;
299                     explain select * from tbl_emp;
300                     ①Explain + sql语句
301                     ②执行计划包含信息 ☆
302                         表头:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
303                     
304                 2.4.3.4 各字段解释
305                     2.4.3.4.1 id
306                         ①select查询的序列号,包含一组数字表示查询中执行select子句或操作表达表的顺序
307                         ②三种情况
308                             一、id相同,执行顺序由上至下
309                                 explain select t2.*
310                                 from t1,t2,t3
311                                 where t1.id = t2.id and t1.id =t3.id
312                                 and t1.other_column = '';
313                             二、id不通,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
314                                 explain select t2.*
315                                 from t2
316                                 where id =(select id
317                                             from t1
318                                             where id = (select t3.id
319                                                         from t3
320                                                         where t3.other_column = ''
321                                                         )
322                                             )
323                                 
324                             三、id相同不同,同时存在,
325                                 id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行 衍生=DERIVED
326                                 explain select t2.* from (
327                                 select t3.id
328                                 from t3
329                                 where t3.other_column = '') s1,t2
330                                 where s1.id = t2.id;
331                                                            
332                     2.4.3.4.2 select_type
333                         ①有哪些
334                             simple、primary、subquery、derived、union、union result
335                         ②查询的类型,主要是用于区别普通查询、联合查询、子查询等复杂查询
336                             一、simple
337                                 简单的select查询,查询中不包含子查询或者union。
338                             二、primary
339                                 查询中若包含任何复杂的子部分,最外层查询则被标记。
340                             三、subquery
341                                 在select或where列表中包含了子查询。
342                             四、derived
343                                 在from列表中包含子查询被标记为derived(衍生)mysql会递归执行这些子查询,把结果放在临时表里。
344                             五、union 
345                                 若第二个select出现在union之后,则被标记为union;
346                                 若union包含在from子句的子查询中,外层select将被标记为:derived
347                             六、union result 从union表获取结果的select
348                             
349                     2.4.3.4.3 table
350                         显示这一行的数据是关于哪张表的
351                         
352                     2.4.3.4.4 type
353                         all、index、range、ref、eq_ref、const,system、null
354                         访问类型排列
355                             type显示的访问类型,是较为重要的一个指标,结果值从最好到最坏一次是:                            
356                             system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL
357                         显示查询使用了何种类型,从最好到最差一次是:
358                             system>const>eq_ref>ref>range>index>ALL,一般来说,得保证查询至少达到range级别,最好能达到ref。
359                             一、system
360                                 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计。                                
361                             二、const
362                                 表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快
363                                 如将逐渐置于where列表中,Mysql就能将该查询转换为一个常量
364                                 例子:explain select * from (select * from t1 where id =1) d1;
365                                 1 primary <derived2> system
366                                 2 derived t1        const
367                             三、eq_ref
368                                 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
369                                 例子:explain select * from t1,t2 where t1.id =t2.id
370                                 1 t2 simple all                                
371                                 1 t1 simple eq_ref
372                             四、ref
373                                 非唯一性索引扫描,返回匹配某个单独值的所有行。
374                                 本质上也是一个索引访问,它返回所有匹配某个单值的行,然而,
375                                 它可能找到过个符合条件的行,所以他应该属于查找和扫描的混合体
376                                 例子:create index idx_col1_col2 on t1(col1,col2);
377                                     select count(distinct col1) from t1;
378                                     explain select * from t1 where col1 = 'ac';
379                             五、range
380                                 只检索给定范围的行,使用每一个索引来选择行,key列显示使用了哪个索引
381                                 一般就是在你的where语句中出现了between、<、>、in等的查询
382                                 这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点而结束语另一点,不用扫描全部索引。
383                                 例子:explain select * from t1 where id between 30 and 60;
384                                 1 simple t1 range
385                                     explain select *from t1 where id in (1,2,6);
386                                 1 simple t1 range
387                             六、index
388                                 full index scan,index与all区别为index类型只遍历索引树,这通常比all快,因为索引文件通常比数据文件小。
389                                 (也就是虽然all和index都是读全表,但index是从索引中读取数据的,而all是从硬盘中读取的)                               
390                                 explain select id from t1;
391                                 1 simple t1 index
392                             七、all
393                                 full table scan,将遍历全表以找到匹配到的行
394                                 备注:一般来说,保证查询至少达到range级别,最好能达到ref
395                                 
396                     2.4.3.4.5 possible_keys
397                         显示可能应用在这张表中的索引:一个或多个
398                         查询涉及到的字段上若存在索引,则将该索引列出,但不一定被查询实际使用                       
399                    
400                     2.4.3.4.6 key
401                         实际使用的索引,如果为null,则没有使用索引
402                         查询中若使用了覆盖索引,则该索引进程出现在key列表中
403                          例子:explain select col1,col2 from t1
404                          1 simple t1 index null idx_col1_col2
405                          
406                     2.4.3.4.7 key_len
407                         表示索引中国使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好
408                         key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出来的
409                         
410                     2.4.3.4.8 ref
411                         显示索引的哪一个列被使用了,如果可能的话是一个常数。哪些列或常量被用于查找索引列上的值
412                         例子:explain select * from t1,t2 where t1.col1 = t2.col1 and t1.col2 = 'ac';
413                         1 t2 all null null null null
414                         1 t1 ref idx_col1_col2 idx_col1_col2 26 shared.t2.col1,const
415                         
416                     2.4.3.4.9 rows
417                         根据表统计信息及索引的选用情况,大致估算出找得到所需的记录所需要读取的行数
418                         例子:
419                     2.4.3.4.10 Extra
420                         包含不适合在其他列中显示但十分重要的额外信息
421                         一、Using filesort
422                             说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。                            msyql中无法利用索引完成的排序操作称为“文件排序”。
423                             例子:explain select col1 from t1 where col1 = 'ac' order by col3\G #中间2没有了
424                             1 simple t1 ref idx_col1_col2_col3 idx_col1_col2_col3 13 const 142 Using where;Using index;Using filesort
425                             例子:explain select col1 from t1 where col1 = 'ac' order by col2,col3\G #性能高
426                             1 simple t1 ref idx_col1_col2_col3 idx_col1_col2_col3 13 const 142 Using where;Using index
427                         二、Using temporary
428                             使用临时表保存了中间结果,mysql在对外查询结果排序时使用临时表,常见于排序order by和分组查询group by。
429                             例子:explain select col1 from t1 where col1 in ('ac','ab','aa') group by col2\G
430                             id simple t1 range idx_col1_col2 idx_col1_col2 13 null 569 Using where;Using index;Using temporary;Using filesort
431                             explain select col1 from t1 where col1 in ('ac','ab') group by col1,col2\G
432                             id simple t1 range idx_col1_col2_col3 idx_col1_col2_col3 26 null 4 Using where;Using index for group by
433                         三、Using index
434                             表示相应的select操作中使用了覆盖索引(Cover Index),避免访问了表的数据行,效率不错!
435                             如果同时出现useing where,表明索引被用来执行索引键值的查找;
436                             如果没有同时出现using where表明索引用来读取该数据而非执行查找动作;
437                             例子:explain select col2 form t1 where col1='ab';
438                             1 ,,, idx_col1_col2 idx_col1_col2 13 const 143 Using where;using index;
439                             explain select col1,col2 form t1
440                             1 simple t1 index null idx_col1_col2 398 null 682 usring index
441                             覆盖索引(Covering Index)
442                                 理解方式一:就是select的数据列只从索引中就能够获取得,不必读取数据行,Mysql可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,
443                                 换句话说查询列要被所建的索引覆盖
444                                 理解方式二:索引是高效查找到行的一个方法,但是一般数据库也能使用索引找到一列的数据,因此它 不必读取整个行,毕竟索引叶子节点存储了他们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了(或覆盖了)满足
445                                 查询结果数据就叫覆盖索引
446                             注意:
447                                 如果要使用覆盖索引,一定注意select列表中只取出需要的列,不可select *。
448                                 因为如果将所有字段一起做索引会导致索引文件过大,查询性能下降。
449                         四、Using where
450                             表明使用了where过滤
451                         五、Using join buffer
452                             使用了连接缓存                          
453                         六、impossible where
454                             where子句的值总是fale,不能用来获取任何元组
455                             例子:explain select * from staffs where name = 'july' and name = 'z3';
456                             1 simple null null null null null null null impossible where
457                         七、select tables optimized away
458                             在没有GROUP BY子句的情况下,基于索引优化MIN/MAX操作或者
459                             对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段再进行计算
460                             查询执行计划生成的阶段即完成优化。
461                         八、distinct
462                             优化distinct操作,在找到第一匹配的元组后即停止找同样值的操作
463                         
464                     
465                 2.4.3.5 热身case
466                     例子:explain select d1.name,(select id from t3) d2
467                         from (select id,name form t1 where t1 where other_column = '') d1
468                         union
469                         (select name,id from t2);
470                         1 primary <derived3> system null null null null 1
471                         3 derived t1    all null    null    null    null    1 Using where
472                         2 subquery  t3  index   null primary    4 null  1   using where
473                         4 union     t2  all     null    null    null    null    1 
474                         null nuion result <uion1,4> all null null null null null
475                         优化sql语句  
476                         第一行(执行顺序4):id列为1,表示是union里的第一个select,select_type列的primary表是该查询为外层查询,table列被标记为<derived3>,
477                         表示结果来自一个衍生表,其中derived3中3代表该查询衍生自第三个select查询,即id为3的select。【select d1.name......】
478                         第二行(执行顺序2):id为3,是整个查询中第三个select的一部分,因查询包含在from中,所以为derived。【select id.name from t1 where other_column=''】
479                         第三行(执行顺序3):select列表中的子查询select_type为subquery,为整个查询中的第二个select。【select id from t3】
480                         第四行(执行顺讯1):select_type为union,说明第四个select是union里的第二个select,最先执行【select name.id from 12】
481                         第五行(执行顺序5):代表从union的临时表中读取行的阶段,table列的<union1,4>表示用第一个和第四个select的结果进行union操作。【两个结果union操作】
482         2.5索引优化
483             2.5.1 索引分析
484                 2.5.1.1 单表
485                     一、建表sql
486                         CREATE TALBE IF NOT EXISTS `article`(
487                         `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
488                         `author_id` INT(10) UNSIGNED NOT NULL,
489                         `category_id` INT(10) UNSIGNED NOT NULL,
490                         `views` INT(10) UNSIGNED NOT NULL,
491                         `comments` INT(10) UNSIGNED NOT NULL,
492                         `title` VARCHAR(255) NOT NULL,
493                         `content` TEXT NOT NULL
494                         );
495                         INSERT INTO `article`(`author_id`,`category_id`,`views`,`comments`,`title`,`content`)VALUES
496                         (1,1,1,1,'1','1'),
497                         (2,2,2,2,'2','2'),
498                         (3,3,3,3,'3','3');
499                     二、案例
500                         #查询category_id为1且comments大于1的情况下,views最多的article_id
501                         EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments>1 ORDER BY views DESC LIMIT 1;
502                         1 simple article all null null null null 3 Using where;Using filesort
503                         show index from article;
504                         #结论:很显然,type是all,即最坏的情况,Extra里还出现了Using filesort,也是最坏的情况,优化是必须的。
505                         #开始优化:
506                         
507                         #1.1 新建索引+删除索引
508                         ##ALTER TABLE 'article' ADD INDEX idx_article_ccv(`category_id`,`comments`,`views`);
509                         create index idx_article_ccv on article(category_id,comments,views);
510                         show index from article;
511                         EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments>1 ORDER BY views DESC LIMIT 1;
512                         1 simple article range idx_article_ccv idx_article_ccv 8 null 1 Using where;Using filesort
513                         调整sql语句
514                         EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments=1 ORDER BY views DESC LIMIT 1;#范围会导致索引失效,同样一个索引条件不一样,查询结果和性能是不一样的,以后跟产品经理提需求尽量提等于,
515                         #产品经理关注产品没关不会关注字段,但是作为研发和产品经理碰需求,尽量引导他,比如这个字段不能为空,不是我们做不出,是影响性能
516                         1 simple article ref idx_article_ccv idx_article_ccv 8 const,const 1 Using where;Using filesort
517                         DROP INDEX idx_article_ccv on article
518                         #1.2 第2次EXPLAIN
519                         EXPLAIN SELECT id,author_id FROM `article` WHERE category_id = 1 AND comments>1 ORDER BY VIEWS DESC LIMIT 1;
520                         EXPLAIN SELECT id,author_id FROM `article` WHERE category_id = 1 AND comments=3 ORDER BY VIEWS DESC LIMIT 1;
521                         #结论:
522                         #type 变成了range,这是可以忍受的。但是extra里使用Using filesort仍是无法忍受的。
523                         #但是我们已经建立了索引,为啥没用呢?
524                         #这是因为按照BTree索引的工作原理
525                         #先排序category_id,
526                         #如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views。
527                         #当comments字段在联合索引里处于中间位置时,
528                         #因comments>1条件是一个范围值(所谓range),
529                         #MySQL无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。
530                         
531                         #1.3删除第一次建立的索引
532                         DROP INDEX idx_article_ccv ON article
533                         
534                         #1.4第2次删除新建索引
535                         #ALTER TABLE `article` ADD INDEX idx_article_cv(`category`,`views`);
536                         create index idx_article_cv on article(category_id,views);
537                         EXPLAIN SELECT id,author_id FROM article WHERE category_id = 1 AND comments>1 ORDER BY views DESC LIMIT 1;
538                         1 simple article ref idx_article_cv 4 const 2 Using where
539                         
540                 2.5.1.2 两表
541                     一、建表
542                         CREATE TABLE IF NOT EXISTS `class`(
543                         `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
544                         `card` INT(10) UNSIGNED NOT NULL,
545                         PRIMARY KEY(`id`)
546                         );
547                         CREATE TALBE IF NOT EXISTS `book`(
548                         `bookid` INT(10) UNSIGNED NOT NULLL AUTO_INCREMENT,
549                         `card` INT(10) UNSIGNED NOT NULL,
550                         PRIMARY KEY(`bookid`)
551                         )
552                         
553                         INSERT INTO class(card) VALUES(FLOOR(1+(RAND()+20)));
554                         INSERT INTO class(card) VALUES(FLOOR(1+(RAND()+20)));
555                         INSERT INTO class(card) VALUES(FLOOR(1+(RAND()+20)));
556                         INSERT INTO class(card) VALUES(FLOOR(1+(RAND()+20)));
557                         INSERT INTO class(card) VALUES(FLOOR(1+(RAND()+20)));
558                         ...20
559                         INSERT INTO book(card) VALUES(FLOOR(1+(RAND()+20)));
560                         INSERT INTO book(card) VALUES(FLOOR(1+(RAND()+20)));
561                         INSERT INTO book(card) VALUES(FLOOR(1+(RAND()+20)));
562                         
563                         select * from book inner join class on book.card = class.card;
564                     二、案例
565                         #下面开始explain分析
566                         EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;
567                         #结论:type 有all
568                         
569                         #添加索引优化
570                         ALTER TABLE `book` ADD INDEX Y(`card`);
571                         
572                         #第2次explain
573                         EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;
574                         #可以看到第二行的type变为了ref,rows也变为了优化比较明显。
575                         #这是由左连接的特性决定的。LEFT JOIN 条件用于确定如何从右表搜索,左边一定都有,
576                         #所以右边是关键点,一定要建立索引。
577                         
578                         #删除旧索引+新建+第3次explain
579                         DROP INDEX Y ON book;
580                         
581                 2.5.1.3 三表
582                     一、建表sql
583                     二、案例
584             2.5.2 索引失效(应该避免)
585             2.5.3 一般性建议
586     3、查询截取分析
587         3.1查询优化
588         3.2慢查询日志
589         3.3批量数据脚本
590         3.4Show Profile
591         3.5全局查询日志
592     4、Mysql锁机制
593         4.1概述
594         4.2表锁
595         4.3行锁
596         4.4页锁
597         4.4小结
598         开锁、加锁速度、死锁、粒度、并发性能只能就具体的应用特点来说那种更适合
599     5、主从复制
600         复制的基本原则
601         复制的最大问题
602         一主一从常见配置

 

标签:高级,查询,索引,Mysql,null,where,id,select
来源: https://www.cnblogs.com/landerhu/p/12512896.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有