MySQL数据库的SQL调优,你时会了吗?
2025-09-16 12:19
可用 explain 可以模拟最佳化装置指派 SQL,数据分析 SQL,看看能否最佳化。
explain 标识的 SQL 不想知道指派,只是返回指派原计划。如果 from 里值得注意侄念过取,仍时会指派该侄念过取,侄念过取的结果将时会摆在临时至多于里。
explain 数据分析的 SQL 里,每念过取一个至多于就时会有一在行记录下来。
更是多内容可问道参考官方文档:
3.1 explain 里各至多的含义
了解到每一至多的意义,掌握最常用那几至多。
3.1.1 id
id 至多的编号是 select 的序至多号,劳几个至多于就有几个 id,并且 id 系数越大大指派优到时级越大高。如果 id 系数相同,就从上往下指派,先前指派 id 为 null 的。
3.1.2 select_type
念过取子类。
primary简便念过取。念过取不值得注意侄念过取和union。
subquery适合于念过取里最外层的 select。
derived值得注意在 from 侄句里的侄念过取。MySQL时会将结果尚滚置一个临时至多于里,也称为区别于至多于(derived的法文含义)。如下:
粘贴
#停止mysql5.7新特性对引申至多于的更名最佳化
set session optimizer_switch='derived_merge=off';
explain select (select 1 from actor where id = 1) from (select * from film where id = 1) der;
• union
回事就是可用了 union 操作符后面的念过取,如下:
3.1.3 table
至多于示这一至多可用的是哪一张至多于。
当 from 侄句里有侄念过取时,table至多是格式,至多于示当前念过取依赖 id=N 的念过取,于是到时指派 id=N 的念过取。如下图:
亦然 union 时,UNION RESULT 的 table 至多的系数为,1和2至多于示参与 union 的 select 在行id。
3.1.4 partitions
可用的哪个西区,需结合至多于西区才可以想到。因为我的例侄都是并未西区的,所以是 null。
3.1.5 type
共同点子类或者访问道期间子类。一般要保证念过取达到 range 级别,最好达到 ref。
从最优到最差:system> const> eq_ref> ref> range> index> ALL。
system, constconst 是 MySQL 能对念过取的某部份转成一个null,如下:
而 system 是 conts 的一个特例,当至多于里只有一条记录下来时,比如说后于 system。
eq_ref可用了null配置明文或者唯一集成配置明文进在行时共同点,总和只时会返回一条适用状况下的记录下来时,等级为 eq_ref。
粘贴
explain select * from film_actor left join film on film_actor.film_id = film.id
1. ref相比较于 eq_ref,它可用的是都是集成或者唯一集成的部份单词,可能时会发现多条适用状况下的记录下来。
range仅限于大石描通常出今天 in(), between ,> ,= 等操作里。可用一个集成来集成任意仅限于的在行。
粘贴
explain select * from actor where id> 1;
1. index这种一般是通过大石描某个二级集成的所有枝叶路由表(回事就是不应认真全至多于大石描,但是这里并用了B+Tree的枝叶路由表是链至多于的特性遍历)。这种模式,虽然相对慢,但是用伸展集成最佳化,机动性上还是要比全至多于大石描(ALL)要好的,因为它%用密闭小,一次IO可以念过更是多汇总天内据。
ALL这个级别没人啥好说是的,就是我们常说是的全至多于大石描。
3.1.6 possible_keys
所述了可能时会可用的集成。
3.1.7 key
意味着时会可用的集成。
3.1.8 key_len
通过这个系数,可以推算出可用到集成的哪些至多(一般针对合组集成可用多些),举个例侄:
film_actor 的合组集成 idx_film_actor_id 由 film_id 和 actor_id 两个 int 至多除此以外是由,并且每个 int 是4二进制。通过结果里的 key_len=4 可推断出念过取可用了第一个至多:film_id至多来指派集成念过取。
粘贴
explain select * from film_actor where film_id = 2;
key_len算出规章如下:
字符串:char(n) 和 varchar(n),5.0.3以后版本里,n除此以外代至多于字符天内,而不是二进制天内,如果是utf-8,一个天内字或字母%1个二进制,一个汉字%3个二进制– char(n):如果尚存汉字间隔就是 3n 二进制
– varchar(n):如果尚存汉字则间隔是 3n + 2 二进制,加在的2二进制用来磁盘字符串间隔,因为varchar是变长字符串
天内系数子类– tinyint:1二进制
– smallint:2二进制
– int:4二进制
– bigint:8二进制
时长子类– date:3二进制
– timestamp:4二进制
– datetime:8二进制
如果配置明文并不需为 NULL,需1二进制记录下来前提为 NULL。集成最大间隔是768二进制,当字符串可避免时,MySQL时会认真一个值得注意左单词集成的处理方式,将前半部份的字符提取走来认真集成。3.1.9 ref
这一至多所述了了在key至多记录下来的集成里,至多于念过取系数所用到的至多或null,常用的有:const(null),配置明文名(例:film.id)。
3.1.10 rows
这一至多是MySQL估计要念过取并检验的在行天内,留意这个不是结果艾薇尔的在行天内。
3.1.11 filtered
通过处理方式过程状况下之后对比总天内的一般而言。
3.1.12 Extra
这一至多展示的是额外信息。常用的不可忽视系数如下:
Using index可用伸展集成。伸展集成回事就是念过取至多是集成配置明文,这样就理应回至多于,减低机动性。因此,我们伸展集成针对的是辅助集成。
Using where可用 where 操作符处理方式结果,并且念过取至多并未被集成伸展。如下:
粘贴
explain select * from actor where name = 'a';
Using index condition念过取的至多没人被集成完全伸展, where 状况下里是一个前导至多的仅限于。
粘贴
explain select * from film_actor where film_id> 1;
Using temporary创设临时至多于来处理方式念过取
(1)actor.name并未集成,此时创设了张临时至多于来distinct。
粘贴
explain select distinct name from actor;
(2)film.name建新立了idx_name集成,此时念过取时extra是using index,并未用临时至多于。
粘贴
explain select distinct name from film;
1. Using filesort可用从外部次序而不是集成次序,汇总天内据量较星期可用明文的系统,否则时会可用磁盘。
(1)actor.name并未创设集成,时会浏览actor整个至多于,保尚存次序操作符name和相关联的id,然后次序name并集成在行记录下来。
粘贴
explain select * from actor order by name;
1.(2)film.name建新立了idx_name集成,此时念过取时extra是using index。
粘贴
explain select * from film order by name;
1.Using filesort 方法至多举如下:
– 单路次序
一次性取走考虑到状况下的所有配置明文,然后在 sort buffer 里次序。用 trace 工具可以想到 sort_mode 信息里所述了 或者
– 双路次序(回至多于次序)
到时根据状况下得到相应的次序配置明文和可以从从外部定位在行汇总天内据的在行ID,然后在 sort buffer 里次序,先前回至多于得到明晰记录下来。用 trace 工具可以想到 sort_mode 信息里所述了 。
– MySQL 通过相对的系统变量 max_length_for_sort_data(预设1024二进制) 的比较大和需念过取的配置明文总比较大来辨别可用哪种次序模式。
如果配置明文的总间隔相等 max_length_for_sort_data,那么可用单路次序。 如果配置明文的总间隔大于 max_length_for_sort_data,那么可用双路次序。 Select tables optimized away可用某些生成函天内(比如 max、min)来访问道期间尚存在集成的某个配置明文后于 Select tables optimized away。
四、全面性!SQL 最佳化保守点说是,SQL 最佳化就是对集成的最佳化。因此,我们要看下各种状况下,如何最佳化集成。
在我看来,SQL最佳化分表列出几种状况:
1.可以停下来集成
不应停下来集成,但是没人停下来 停下来集成了,但是没人到最优(explain 数据分析,type 一般我们尽快有数到达 range 这个级别) order by 和 group by 最佳化2.不了停下来集成(客观现实上的)或者 type 是 index,而且汇总天内据量大
了解到适用集成的状况,问道不用只有面试时会说是,文书工作就不回事了(汇总天内据量很小,从从外部劳没人事;大的话,考虑应运而生其他技术解决,如 :Redis, MongoDB, elasticsearch等)3.小至多于特别设计大至多于
4.count 念过取最佳化
5.如何建新集成
该在哪个配置明文建新集成 哪些配置明文要可用合组集成 至多于配置明文的内部设计(汇总天内据子类,比较大)Note : 单个集成生不有效性期,怎么处理方式还是相对简便的,所以问道注意只针对合组集成认真数据分析。
问道注意到时建新至多于和造汇总天内据:
粘贴
CREATE TABLE 在在employees在在 (
在在id在在 int(11) NOT NULL AUTO_INCREMENT,
在在name在在 varchar(24) NOT NULL DEFAULT '' COMMENT '人名',
在在age在在 int(11) NOT NULL DEFAULT '0' COMMENT '年长',
在在position在在 varchar(20) NOT NULL DEFAULT '' COMMENT '职位',
在在hire_time在在 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时长',
PRIMARY KEY (在在id在在),
KEY 在在idx_name_age_position在在 (在在name在在,在在age在在,在在position在在) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100004 DEFAULT CHARSET=utf8 COMMENT='文书工作人员记录下来至多于';
CREATE TABLE 在在actor在在 (
在在id在在 int(11) NOT NULL,
在在name在在 varchar(45) DEFAULT NULL,
在在update_time在在 datetime DEFAULT NULL,
PRIMARY KEY (在在id在在)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='演员至多于';
CREATE TABLE 在在film在在 (
在在id在在 int(11) NOT NULL AUTO_INCREMENT,
在在name在在 varchar(10) DEFAULT NULL,
PRIMARY KEY (在在id在在),
KEY 在在idx_name在在 (在在name在在) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='电影至多于';
CREATE TABLE 在在film_actor在在 (
在在id在在 int(11) NOT NULL,
在在film_id在在 int(11) NOT NULL,
在在actor_id在在 int(11) NOT NULL,
在在remark在在 varchar(255) DEFAULT NULL,
PRIMARY KEY (在在id在在),
KEY 在在idx_film_actor_id在在 (在在film_id在在,在在actor_id在在)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电影演员里间至多于'
其里文书工作人员至多于放入了10W+汇总天内据。
4.1 常用的不应停下来集成,但是没人停下来
合组集成第一个配置明文不能处理方式过程大部份汇总天内据,造成回至多于效能较高,停下来全至多于大石描的 cost 更是小。粘贴
explain SELECT * FROM 在在employees在在 where 在在name在在 like "sai%" and age = 22 and position = 'dev';
当然我们也可以必需自愿停下来集成,如下:
粘贴
explain SELECT * FROM 在在employees在在 force index(idx_name_age_position) where 在在name在在 like "sai%" and age = 22 and position = 'dev';
1.不过,停下来集成一定机动性就更是好吗?我们测试下。
粘贴
---- 停止念过取缓尚存
SET GLOBAL query_cache_size = 0;
SET GLOBAL query_cache_type = 0;
---- 耗时 0.064s
SELECT * FROM 在在employees在在 WHERE 在在name在在 LIKE "sai%" AND age = 22 AND position = 'dev';
---- 耗时 0.079s
SELECT * FROM 在在employees在在 force index(idx_name_age_position) where 在在name在在 like "sai%" and age = 22 and position = 'dev';
别看我这相差很小,我这只是至多于至多不多,配置明文很小,汇总天内据量也不算太多,所以相差很小,如果至多于更是大的话,相差就时会相对引人注意了。意味着文书工作里,我们很难确切停下来集成的 cost 就一定相等全至多于大石描的。因此,我们一般不自愿停下来集成。
最佳化可行性:
我想让 MySQL自己去停下来集成,而不是我自愿停下来集成。怎么办呢?回事纸片已经写到了,这里是因为第一个配置明文处理方式过程不多,造成回至多于效能较高。既然如此,我们让它不回至多于不就好了吗?可用伸展集成最佳化,就是我们念过取至多的配置明文都是可用的这个集成大树根建新了集成的配置明文,这样就不需回至多于了。如下:
粘贴
explain SELECT id,在在name在在,age,position FROM 在在employees在在 where 在在name在在 like "sai%" and age = 22 and position = 'dev';
---- 耗时 0.051s
SELECT id,在在name在在,age,position FROM 在在employees在在 where 在在name在在 like "sai%" and age = 22 and position = 'dev';
扩展到:
我们可用 in 和 or 时,有时停下来集成,有时不停下来,回事是因为 MySQL 辨别停下来集成的cost不如全至多于大石描的。 我们这里用了 like 'keyword%',这里相关到一个概念叫集成自始。回事就是,MySQL 5.6 前,对于表列出的SQL,如果是停下来集成的话,它时会到时根据 name 处理方式过程取得null,进在行时回至多于丢掉汇总天内据后,先去对比 age 和 position。MySQL 5.6 回应进在行时了最佳化——集成自始,根据 name 处理方式过程后,不到时回至多于,而是从从外部去对比 age 和 position,先前取得的null才回至多于劳汇总天内据。留意:1、集成自始只使用二级集成;2、不是 like 'keyword%' 就一定可用集成自始。粘贴
SELECT * FROM 在在employees在在 WHERE 在在name在在 LIKE "sai%" AND age = 22 AND position = 'dev';
1. 分页不停下来集成分页念过取,的系统极为常用的念过取,同意大家学习完后,赶紧看下自己负责管理的分页功能前提停下来集成了,或者前提停下来了集成但是还能最佳化。表列出,看例侄来说是一些最佳化手段。
粘贴
select * from employees limit 10000, 10;
1.这 SQL 回事是去了10010条记录下来出来,然后先舍弃前面的一万条。因此汇总天内据量大的话,回事效能是极为较高的。
一些最佳化可行性:
1.和的产品同事商量,给一些一定有的念过取状况下或者隐密的念过取状况下,给这些状况下可用上集成。
这个可行性是最简便并且从从外部的。
2.像我这里记录下来的id是整年且自增的状况下:
粘贴
explain select * from employees where id> 10000 limit 10;
1.属于取巧,通过null集成可用 where 从从外部选取掉前面10000条记录下来。
弱点:
(1) 如果 id 不是整年且自增,那么这种模式就不在行。
(2)不是可用null次序,这种状况也不在行。
3.非null次序,不用ID整年自增也能有效性期。
粘贴
---- 0.085s
select * from employees order by 在在name在在 desc limit 10000, 10;
首到时想到伸展集成最佳化,看看能否这样干粘贴
explain select 在在name在在, age, position from employees order by 在在name在在 desc limit 10000, 10;
---- 0.077s
select 在在name在在, age, position from employees order by 在在name在在 desc limit 10000, 10;
扩展到:
粘贴
---- 我们常显然 like 以正则表达式末尾,集成时会重新启动,但回事也可以通过伸展集成,让集成有效性期。
explain select 在在name在在, age, position from employees where 在在name在在 like '%sai%';
不能可用伸展集成,用了非null次序,全至多于大石描的或许:MySQL 5.6~5.7 版本的最佳化装置显然停下来二级集成先回至多于的效能不如全至多于大石描,这时是不想停下来集成的(但是也有例外,select * from employees order by name desc limit 10 就时会停下来集成,因为只需拿10条记录下来,这需求量足够小,具体内容可可以看这个该网站,写到得很差:)。减低效率如下:
(1)
粘贴
explain select e.* from employees e inner join (select id from employees order by 在在name在在 desc limit 10000, 10) t on t.id = e.id;
---- 0.045s
select e.* from employees e inner join (select id from employees order by 在在name在在 desc limit 10000, 10) t on t.id = e.id;
这里回事就是并用了二级集成,丢掉了10010条汇总天内据,并且按照 name 排好序,由于这里的侄念过取只要 id,所以不需回至多于,然后先通过 join 就能并用null集成慢速丢掉记录下来。
(2)当然除了这种模式,我们也可以自愿停下来集成,因为我们回事这里二级集成只有一个,并且 name 是前导至多,所以我这个与此相关停下来集成机动性肯定比全至多于大石描好。因此,我们也可以必需自愿停下来集成。
粘贴
---- 0.011s
select * from employees force index(idx_name_age_position) order by 在在name在在 desc limit 10000, 10;
不适用最左前提我们集成之所以可以帮我们慢速发现目标汇总天内据,是因为它的汇总天内据结构的在结构上。其里有序这一特征极为不可忽视,如果不考虑到,那么肯定是不想停下来集成的(具体内容可或许要回到连续性二叉念过取大树,先到二分法。因为不是这里的全面性,所以不告一段落说是什么)。
在集成至多上认真了表列出操作:– 对集成至多是用了函天内
– 对集成至多认真了多态
粘贴
---- 多态时会有特例,当我们转成日期仅限于念过取时,也许停下来集成。
ALTER TABLE 在在employees在在 ADD INDEX 在在idx_hire_time在在 (在在hire_time在在) USING BTREE ;
EXPLAIN select * from employees where hire_time>='2018‐09‐30 00:00:00' and hire_time
='2018‐09‐30 23:59:59';
根据念过取状况下处理方式过程的汇总天内据不多,造成最佳化装置显然停下来集成不如全至多于大石描。回事第一个与此相关已经相关到了,但是这里针对的是不等于, not in, not exists, , is null, is not null 等等,这些能比如说到多条记录下来的写到法。
4.2 order by 和 group by 最佳化
次序和两组的最佳化回事是极为像的,本质是到时次序后两组,遵循集成创设以此类推的最左比如说前提。因此,这里以次序为例。
这个该网站有说是什么到无念过取状况下的次序的与此相关,我这里就从从外部上图了,如下:
接下来写到的都是有念过取状况下的状况。
粘贴
explain select * from employees where 在在name在在 = 'sai999' and position = 'dev' order by age;
粘贴
---- 这里并未停下来集成,是因为不适用最左前提,上到了 age
explain select * from employees where 在在name在在 = 'sai999' order by position;
粘贴
---- 这样就时会停下来集成了,次序了
explain select * from employees where 在在name在在 = 'sai999' order by age, 1position;
粘贴
---- 又不停下来集成了,因为 age 和 position 以此类推不对了,不适用我们集成的以此类推
explain select * from employees where 在在name在在 = 'sai999' order by position, age;
粘贴
---- 重写成这样,就又可以停下来集成了,因为 age 是个null了,所以在次序里被最佳化,并未和集成以此类推冲突
explain select * from employees where 在在name在在 = 'sai999' and age = 999 order by position, age;
粘贴
---- 这里虽然适用集成以此类推,但是 age 是升序,而 position 是降序,所以不停下来集成。问道道是 MySQL 8 支持这种念过取模式,我没人装设8就不测试了
explain select * from employees where 在在name在在 = 'sai999' order by age asc, position desc;
粘贴
---- 曾说是我们合组集成的 B+Tree 汇总天内据结构,当 name 有两个系数时,得出的结果集对于 age, position 而言是无序的,所以不了停下来集成
explain select * from employees where 在在name在在 in ('sai100', 'sai101') order by age, position;
粘贴
---- 仅限于念过取,最佳化装置辨别机动性不如全至多于大石描的话,将不停下来集成
explain select * from employees where 在在name在在> 'a' order by 在在name在在;
粘贴
---- 可以可用伸展集成最佳化
explain select 在在name在在, age, position from employees where 在在name在在> 'a' order by 在在name在在;
MySQL 支持两种次序模式 filesort 和 index, Using index 是大石描集成收尾的次序,而 Using filesort 是并用明文的系统甚至磁盘收尾次序的。因此,index 效能高,filesort 效能较高。
4.3 小至多于特别设计大至多于
当我们认真多至多于共同点念过取时,常常时会听到小至多于特别设计大至多于。这里要了解到什么是小至多于,什么是大至多于,为什么是小至多于特别设计大至多于,MySQL 用了什么正则表达式。
问道注意以两张至多于共同点为例,概述概念
什么是小至多于,什么是大至多于?不是至多于汇总天内据量少那张至多于就是大至多于!!!而是经过我们的状况下选取后,比如说汇总天内据相对比较大的那张至多于就是小至多于,另外一张就是大至多于。
所谓的小至多于特别设计大至多于就是:到时劳小至多于,然后通过共同点配置明文去比如说大至多于汇总天内据。
MySQL 的至多于共同点常用有两种正则表达式:
Nested-Loop Join 正则表达式(NLJ) Block Nested-Loop Join 正则表达式(BNL)4.3.1 NLJ,嵌套循环连接正则表达式
这个正则表达式就是一次一在行地从特别设计至多于里念过取,通过共同点配置明文在被特别设计至多于里取走考虑到状况下的在行,然后取走两张至多于的结果合集。
粘贴
explain select * from uuc_user u inner join uuc_user_role ur on ur.user_id = u.id;
从指派原计划可以看出:
uuc_user_role 是特别设计至多于,并且大石描了9条记录下来(至多于里只有9条记录下来),然后通过 user_id 去共同点了 uuc_user(被特别设计至多于)。留意:最佳化装置一般时会优到时必需小至多于特别设计大至多于,我们 SQL 写到的至多于的到时后以此类推也许时会被最佳化。
纸片 SQL 的大致模式上如下:
到时从 uuc_user_role 里念过取一在行记录下来(如果有念过取状况下,时会根据念过取状况下处理方式过程结果里取一条) 得到共同点配置明文,通过共同点配置明文到 uuc_user 发现比如说记录下来 对第二步取得的记录下来,根据念过取状况下取得的记录下来跟第一步取得的记录下来进在行时更名,返回客户端 重复纸片三步念过取结果如下(由于汇总天内据太多,手工剪裁图了)
NLJ这个过程时会念过取 ur 所有汇总天内据(9在行记录下来),每次念过一在行并丢掉 user_id 的系数,然后取得相关联的 uuc_user 里的记录下来(这就是又大石了一次集成取得一在行汇总天内据)。意味着是,整个过程大石描了18在行记录下来。留意:如果被特别设计至多于的共同点配置明文并未集成,可用NLJ正则表达式机动性较较高,MySQL时会必需可用 BNL 正则表达式。
扩展到:如果我这里可用的是 left join,这时,左侧的是特别设计至多于,左面的是被特别设计至多于;right join 则刚好相反。
粘贴
explain select * from uuc_user u left join uuc_user_role ur on ur.user_id = u.id;
4.3.2 BNL,基于块的嵌套循环连接正则表达式
把特别设计至多于的汇总天内据念过入 join_buffer 里,然后大石描被特别设计至多于,把被特别设计至多于每一在行取走来和 join_buffer 里的汇总天内据认真比如说。
纸片扩展到已经浮现了 BNL 正则表达式的例侄了,我就从从外部可用了。
粘贴
select * from uuc_user u left join uuc_user_role ur on ur.user_id = u.id;
这条 SQL 的模式上大致如下:
把 uuc_user 所有记录下来滚入 join_buffer 劳 uuc_user_role 的记录下来和 join_buffer 里的汇总天内据比如说 返回考虑到状况下的汇总天内据整个过程大石描了 uuc_user 至多于225条记录下来和 uuc_user_role 至多于9条记录下来,总大石描在行天内为234在行。明文的系统相对最大次天内 = 225 * 9 = 2025(次),曾说是 for 循环的代小数点就回事了。
两个弊端:
如果明文的系统不够大,即 join_buffer 滚不下 uuc_user 的汇总天内据怎么办? 为什么被特别设计至多于的共同点配置明文并未集成时会必需 BNL 正则表达式呢?答案:
明文的系统不够,那就分段滚。打个比方我明文的系统并不需滚下200条记录下来,我这里225,那么我一次滚200,分两次滚完就好了。join_buffer 预设系数是256k。 如果共同点配置明文并未集成,可用 NLJ 正则表达式的话,那么我们的相对都需停下来磁盘大石描(等于是念过取并未用到集成)。这时,都没人用到集成的话,我明文的系统相对的机动性要比磁盘的好。因此,可用 BNL。但是有集成的话,我们可以通过集成大大减低念过取机动性(回事就是增大IO),所以时会可用 NLJ。4.3.3 多至多于共同点的最佳化
互联网母公司回事一般不并不需认真多至多于共同点,如果认真了共同点,总和不超过3张至多于。多至多于共同点时,共同点配置明文一定要有集成,并且汇总天内据子类保持一致。为什么这么尽快?从从外部或许,艾哈迈德标准化(老大都这样标准化,小弟跟着认真,没人毛病)。根本或许?看《高机动性MySQL》,这本书推荐阅念过。
共同点配置明文加在集成,让 MySQL 认真 join 时适度必需 NLJ 正则表达式。 小至多于特别设计大至多于,如果自己能回事哪张至多于肯定是小至多于,我们可以可用 straight_join,省却最佳化装置的辨别时长。粘贴
---- 像 select * from uuc_user u inner join uuc_user_role ur on ur.user_id = u.id; 这 SQL
---- 我们可以最佳化成问道注意的 SQL,用左侧的至多于特别设计左面的至多于
explain select * from uuc_user_role ur straight_join uuc_user u on ur.user_id = u.id;
4.3.4 in 和 exsits
前提还是小至多于特别设计大至多于
假设 A 至多于是左至多于,B 至多于是侄念过取的至多于。当 A 至多于是大至多于, B 至多于是小至多于时,可用 in。
粘贴
select * from A where id in (select id from B)
当 A 至多于是小至多于, B 至多于是大至多于时,可用 exsits。
粘贴
---- exists(subquery)只返回 true 或 false,官方也有说是过意味着指派时会忽略念过取至多。因此,select * 和 select 1 没人区别。
---- exists侄念过取意味着指派过程是被最佳化了的,不是我们前理解的逐条比如说。
select * from A where exists (select 1 from B where B.id = A.id)
4.4 count 念过取最佳化
讨论区;大多详细资料说是,要count(id)或者count(1),不用count(*),到底看看这样呢?我们今天就来有系统一下。
粘贴
---- 临时停止念过取缓尚存,看实验的真正时长
set global query_cache_size=0;
set global query_cache_type=0;
---- 首到时问道注意四条操作符取得的指派原计划都是一样的,说是明并不一定这四个SQL的指派效能不应是仅有的
explain select count(1) from employees; ---- 有时0.03仅有,有时0.015s仅有
explain select count(id) from employees;---- 保持稳定在0.015s仅有
explain select count(*) from employees;---- 保持稳定在0.015s仅有
explain select count(在在name在在) from employees;---- 保持稳定在0.015s仅有
具体内容可耗时如下(回事,随着人工智慧的状态各不相同,时会有出入,但是多次测试时会发现,这截图的次序结果是多天内)。
因此,我们可以看出 count(*) 少用,机动性较差是谣言,可以滚心可用。这是因为 MySQL 5.6+ 时会对 count(*) 进在行时最佳化,所以指派效能还是很高的。
hire_time 慢的或许是因为并未集成。
4.5 如何建新集成
老生常谈的样子了,面试也经常问道,这里就认真个总结。
对于如何建新集成这个弊端,我个人看来不应从表列出几个并不一定思维:
什么情景要建新集成 不应挑选出哪些配置明文建新集成,配置明文的比较大,配置明文的子类 集成的需求量4.5.1 什么情景要建新集成
高频念过取,且汇总天内据少,能够通过集成选取少汇总天内据 至多于共同点 汇总,次序,两组生成4.5.2 不应挑选出哪些配置明文建新集成,配置明文的比较大,配置明文的子类
高频念过取,更是新较高频,并且可以处理方式过程少汇总天内据的配置明文 使用至多于共同点的共同点配置明文 使用次序,两组,汇总等等的配置明文 作为建新集成的配置明文适度小,可以减缓大树的总体,具体内容可规章看问道注意的艾哈迈德标准化4.5.3 集成的需求量
集成的需求量要适度的少。
因为集成是时会%密闭的; 记录下来更是新汇总天内据库记录下来时,是有保证集成的效益的,需求量越大多,保证效益越大高; 一张至多于集成过多,当一个状况下发现多个集成都有效性期时,最佳化装置一般时会挑选出机动性最好的那个集成来用,需求量多,最佳化装置的挑选出的效益也时会上升。4.6 集成内部设计前提
1.代小数点到时在行,集成后上
只有对的系统有了一定全局观,才回事哪些地方需用集成,多半 SQL 是怎样的,我不应如何建新集成。这样,我们就能有效性增大故意的集成,认真到合组集成适度伸展状况下。
2.适度不用在处理方式过程汇总天内据不多的配置明文建新立集成,如:性别歧视。
3.where 与 order by 冲突时,优到时处理方式 where。
译者概述
蔡柱李卓,51CTO社区编辑,从事Java后部开发8年,认真过传统原计划广电BOSS的系统,后全心投入互联网一站式,负责管理过订单,TMS,里间件等。
。昆明看白癜风去哪家好驻马店白癜风医院哪家更好
西安皮肤病医院哪里好
郑州妇科医院哪家医院最好
沈阳看儿科哪家医院比较好
-
“银丝带”与“大雪花”翩翩起舞 冬奥火炬台将视作永久性雕塑
杭州2022年杭州亚运会和夏残奥会杭州亚运台,它有一个好听的名字叫“MLT-台”。据了解,座落国家Stadium、应天和包头的三个埸杭州亚运台在杭州杭州亚运会、夏残奥会结束后,将沦为经常性雕像。
-
93㎡新房刚摆上生活用品,颜值最高的居然是200块买的酒柜小吧台!
常常兼职还是挺忙的,卖的93㎡的两居室,装潢都是直接包给装潢公司想到的全包,物料什么的都是去装潢公司选的,前期装潢欠缺晚期的一些灯具洁具和门内的装上,完全完工也红豆了2个年底的小时,没多久箍上手
- 10-22谷仓门被年轻人偏爱,可不仅是因为好看!
- 10-22神秘幸存者5年,世界第一超模丑成鬼?!她用亲身经历曝光一个真相...
- 10-22康姨母指导鞠婧祎绑戏,嫦娥变丑吓哭观众,侯孝贤曹云打脸景甜
- 10-22Jennie金智妮真放得开,露脐装打扮竟然翻车,肉嘟嘟小肚子太招摇
- 10-22舒淇、李宇春撞衫比美,穿著丝绒锦鲤裙秀身材,后者曼妙身姿太意外
- 10-22大拙若巧——漫谈泽州大阳汤关帝成汤殿建筑风格
- 10-22“逆生长”陈意涵豪宅:藏满不老“秘籍”,角落都是她的发明成果
- 10-22预告|魔都腔调 极镱中心全球旗舰店开业
- 10-22量房日记:国信国际公馆160㎡四室两厅两卫,好外观设计,从量房开始
- 10-22日本房子不装地中纬度也不冷,原本他们是这样设计的,真后悔太晚听说