Deprecated
: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in
/www/wwwroot/testblog.58heshihu.com/var/Widget/Archive.php
on line
1057
首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
28
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
1
篇与
的结果
2023-08-12
一张图彻底搞定 explain
一张图彻底搞定 explainexplain 关键字可以模拟 MySQL 优化器执行 SQL 语句,可以很好的分析 SQL 语句或表结构的性能瓶颈。explain 的用途表的读取顺序如何数据读取操作有哪些操作类型哪些索引可以使用哪些索引被实际使用表之间是如何引用每张表有多少行被优化器查询......explain 的执行效果mysql> explain select * from subject where id = 1 \G id: 1select_type: SIMPLE table: subjectpartitions: NULL type: constpossible_keys: PRIMARY key: PRIMARYkey_len: 4 ref: const rows: 1filtered: 100.00 Extra: NULLexplain 包含的字段id //select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序select_type //查询类型table //正在访问哪个表partitions //匹配的分区type //访问的类型possible_keys //显示可能应用在这张表中的索引,一个或多个,但不一定实际使用到key //实际使用到的索引,如果为NULL,则没有使用索引key_len //表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度ref //显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值rows //根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数filtered //查询的表行占表的百分比Extra //包含不适合在其它列中显示但十分重要的额外信息图片版文字版id 字段id 相同执行顺序从上至下例子:explain select subject.* from subject,student_score,teacher where subject.id = student_id and subject.teacher_id = teacher.id;读取顺序:subject > teacher > student_scoreid 不同如果是子查询,id的序号会递增,id的值越大优先级越高,越先被执行例子:explain select score.* from student_score as score where subject_id = (select id from subject where teacher_id = (select id from teacher where id = 2));读取顺序:teacher > subject > student_scoreid 相同又不同id如果相同,可以认为是一组,从上往下顺序执行在所有组中,id值越大,优先级越高,越先执行例子:explain select subject.* from subject left join teacher on subject.teacher_id = teacher.id -> union -> select subject.* from subject right join teacher on subject.teacher_id = teacher.id; 读取顺序:2.teacher > 2.subject > 1.subject > 1.teacherselect_type 字段SIMPLE简单查询,不包含子查询或Union查询例子:explain select subject.* from subject,student_score,teacher where subject.id = student_id and subject.teacher_id = teacher.id;PRIMARY查询中若包含任何复杂的子部分,最外层查询则被标记为主查询例子:explain select score.* from student_score as score where subject_id = (select id from subject where teacher_id = (select id from teacher where id = 2));SUBQUERY在select或where中包含子查询例子:explain select score.* from student_score as score where subject_id = (select id from subject where teacher_id = (select id from teacher where id = 2));DERIVED在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表中备注:MySQL5.7+ 进行优化了,增加了derived_merge(派生合并),默认开启,可加快查询效率UNION若第二个select出现在uion之后,则被标记为UNION例子:explain select subject.* from subject left join teacher on subject.teacher_id = teacher.id -> union -> select subject.* from subject right join teacher on subject.teacher_id = teacher.id;UNION RESULT从UNION表获取结果的select例子:explain select subject.* from subject left join teacher on subject.teacher_id = teacher.id -> union -> select subject.* from subject right join teacher on subject.teacher_id = teacher.id;type 字段NULL>system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL //最好到最差备注:掌握以下10种常见的即可NULL>system>const>eq_ref>ref>ref_or_null>index_merge>range>index>ALLNULLMySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引例子:explain select min(id) from subject;system表只有一行记录(等于系统表),这是const类型的特列,平时不大会出现,可以忽略const表示通过索引一次就找到了,const用于比较primary key或uique索引,因为只匹配一行数据,所以很快,如主键置于where列表中,MySQL就能将该查询转换为一个常量例子:explain select * from teacher where teacher_no = 'T2010001';eq_ref唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描例子:explain select subject.* from subject left join teacher on subject.teacher_id = teacher.id;ref非唯一性索引扫描,返回匹配某个单独值的所有行本质上也是一种索引访问,返回所有匹配某个单独值的行然而可能会找到多个符合条件的行,应该属于查找和扫描的混合体例子:explain select subject.* from subject,student_score,teacher where subject.id = student_id and subject.teacher_id = teacher.id;ref_or_null类似ref,但是可以搜索值为NULL的行例子:explain select * from teacher where name = 'wangsi' or name is null;index_merge表示使用了索引合并的优化方法例子:explain select * from teacher where id = 1 or teacher_no = 'T2010001' .range只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引一般就是在你的where语句中出现between、<>、in等的查询。例子:explain select * from subject where id between 1 and 3;indexFull index Scan,Index与All区别:index只遍历索引树,通常比All快因为索引文件通常比数据文件小,也就是虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘读的。例子:explain select id from subject;ALLFull Table Scan,将遍历全表以找到匹配行例子:explain select * from subject;table 字段数据来自哪张表possible_keys 字段显示可能应用在这张表中的索引,一个或多个查询涉及到的字段若存在索引,则该索引将被列出,但不一定被实际使用key 字段 实际使用到的索引,如果为NULL,则没有使用索引查询中若使用了覆盖索引(查询的列刚好是索引),则该索引仅出现在key列表key_len 字段 表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度在不损失精确度的情况下,长度越短越好key_len显示的值为索引字段最大的可能长度,并非实际使用长度即key_len是根据定义计算而得,不是通过表内检索出的ref 字段 显示索引的哪一列被使用了,如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值rows 字段 根据表统计信息及索引选用情况,大致估算出找到所需的记录所需读取的行数partitions 字段 匹配的分区filtered 字段 查询的表行占表的百分比Extra 字段 包含不适合在其它列中显示但十分重要的额外信息Using filesort说明MySQL会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取MySQL中无法利用索引完成的排序操作称为“文件排序”例子:explain select * from subject order by name;Using temporary使用了临时表保存中间结果,MySQL在对结果排序时使用临时表,常见于排序order by 和分组查询group by例子:explain select subject.* from subject left join teacher on subject.teacher_id = teacher.id -> union -> select subject.* from subject right join teacher on subject.teacher_id = teacher.id;Using index表示相应的select操作中使用了覆盖索引(Covering Index),避免访问了表的数据行,效率不错!如果同时出现using where,表明索引被用来执行索引键值的查找如果没有同时出现using where,表明索引用来读取数据而非执行查找动作例子:explain select subject.* from subject,student_score,teacher where subject.id = student_id and subject.teacher_id = teacher.id;备注:覆盖索引:select的数据列只用从索引中就能够取得,不必读取数据行,MySQL可以利用索引返回select列表中的字段,而不必根据索引再次读取数据文件,即查询列要被所建的索引覆盖Using where使用了where条件例子:explain select subject.* from subject,student_score,teacher where subject.id = student_id and subject.teacher_id = teacher.id;Using join buffer使用了连接缓存例子:explain select student.,teacher.,subject.* from student,teacher,subject;impossible wherewhere子句的值总是false,不能用来获取任何元组例子:explain select * from teacher where name = 'wangsi' and name = 'lisi';distinct一旦mysql找到了与行相联合匹配的行,就不再搜索了例子:explain select distinct teacher.name from teacher left join subject on teacher.id = subject.teacher_id;Select tables optimized awaySELECT操作已经优化到不能再优化了(MySQL根本没有遍历表或索引就返回数据了)例子:explain select min(id) from subject;使用的数据表create table subject( -> id int(10) auto_increment, -> name varchar(20), -> teacher_id int(10), -> primary key (id), -> index idx_teacher_id (teacher_id));//学科表create table teacher( -> id int(10) auto_increment, -> name varchar(20), -> teacher_no varchar(20), -> primary key (id), -> unique index unx_teacher_no (teacher_no(20)));//教师表create table student( -> id int(10) auto_increment, -> name varchar(20), -> student_no varchar(20), -> primary key (id), -> unique index unx_student_no (student_no(20)));//学生表create table student_score( -> id int(10) auto_increment, -> student_id int(10), -> subject_id int(10), -> score int(10), -> primary key (id), -> index idx_student_id (student_id), -> index idx_subject_id (subject_id));//学生成绩表alter table teacher add index idx_name(name(20));//教师表增加名字普通索引数据填充: insert into student(name,student_no) values ('zhangsan','20200001'),('lisi','20200002'),('yan','20200003'),('dede','20200004');insert into teacher(name,teacher_no) values('wangsi','T2010001'),('sunsi','T2010002'),('jiangsi','T2010003'),('zhousi','T2010004');insert into subject(name,teacher_id) values('math',1),('Chinese',2),('English',3),('history',4);insert into student_score(student_id,subject_id,score) values(1,1,90),(1,2,60),(1,3,80),(1,4,100),(2,4,60),(2,3,50),(2,2,80),(2,1,90),(3,1,90),(3,4,100),(4,1,40),(4,2,80),(4,3,80),(4,5,100);
2023年08月12日
15 阅读
0 评论
0 点赞