字符串字段当条件查询的时候需要加引号吗_如此详细的SQL优化教程,是你需要的吗?...

基础数据准备

0214abcc8268da5085b1be5b170446b1.png

二:五百万数据插入

上面插入几条测试数据,在使用索引时还需要插入更多的数据作为测试数据,下面就通过存储过程插入500W条数据作为测试数据

c8dcc1bf55538b272b61a02e9bb4e6fe.png

三:使用索引和不使用索引的比较

没有添加索引前一个简单的查询用了1.79秒

36d1e709248c507662f04b22aaf70e21.png

创建索引,然后再查询可以看到耗时0.00秒,这就是索引的威力

a4c56cd2514196e8ca370228f68c3ad9.png
ce8d8b989416a3927d36e93713288d10.png
4482ce59f64dac125d4d3b45fee70e36.png

四:explain命令

2ff0bdc70b1cee4e072db1c5e9ba20e2.png
112c656edcd1f759791f03b6144b7f16.png
6d57b2c31e98b14e348394a9ccfd32ce.png
36e1adc6989a34802c972441048c91af.png

explain命令用于查看sql执行时是否使用了索引,是优化SQL语句的一个非常常用而且非常重要的一个命令, 上面中的key字段表示查询使用到的索引即使用了idx_username索引

id: SELECT识别符。这是SELECT的查询序列号

select_type: 查询类型

simple: 简单表即不适用表连接或者子查询

primary: 主查询,即外层的查询

subquery: 子查询内层第一个SELECT,结果不依赖于外部查询

dependent subquery: 子查询内层第一个

select: 依赖于外部查询

union: UNION语句中第二个SELECT开始后面所有SELECT

union result union 中合并结果

DERIVED

table:查询的表

partitions

type:扫描的方式,all表示全表扫描

all : 全表扫描

index: 扫描所有索引

range: 索引范围扫描,常见于< <=、>、>=、between、

const: 表最多有一个匹配行, 常见于根据主键或唯一索引进行查询

system: 表仅有一行(=系统表)。这是const联接类型的一个特例

ref

possible_keys: 该查询可以利用的索引,可能同一个查询有多个索引可以使用,如果没有任何索引显示null

key: 实际使用到的索引,从Possible_key中所选择使用索引,当有多个索引时,mysql会挑出一个最优的索引来使用

key_len: 被选中使用索引的索引长度

ref:

多表连接时的外键字段

const

rows: 估算出结果集行数,该sql语句扫描了多少行,可能得到的结果,MySQL认为它执行查询时必须检查的行数

filtered:

Extra:额外重要的信息

no tables: Query语句中使用FROM DUAL 或不含任何FROM子句

using filesort : 使用文件排序,最好能避免这种情况

Using temporary: 某些操作必须使用临时表,常见 GROUP BY ; ORDER BY

Using where: 不用读取表中所有信息,仅通过索引就可以获取所需数据;

Using join buffer (Block Nested Loop)

Using index condition

Using sort_union(索引名)

查看索引的使用情况:

show status like ‘Handler_read%’;

Handler_read_key: 越高越好

Handler_read_rnd_next:越低越好

4de3703971a61fc208c5542e38a667a0.png

查询优化器:

重新定义表的关联顺序(优化器会根据统计信息来决定表的关联顺序)

将外连接转化成内连接(当外连接等于内连接)

使用等价变换规则(如去掉1=1)

优化count()、min()、max()

子查询优化

提前终止查询

in条件优化

mysql可以通过 EXPLAIN EXTENDED 和 SHOW WARNINGS 来查看mysql优化器改写后的sql语句

26d5b476f8b011f88ec5199c8347a76d.png

五:走索引的情况和不走索引的情况

1. in走索引

in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内。

d0d91a5087826153efcbcde54af3f012.png

2. 范围查询走索引

baf773512837ca1746765bcc8317e3c4.png

3. 模糊查询只有左前缀使用索引

40dfd09a53570e54f745278d3a0829a9.png

4. 反向条件不走索引 != 、 <> 、 NOT IN、IS NOT NULL

8a01a80daa6110b7f51bc8fd03adb204.png
7a875a573e2ce7ae418c7490659026d7.png
338d3f5b1f1a846ae859a6f1bc037e0c.png

5. 对条件计算(使用函数或者算数表达式)不走索引

使用函数计算不走索引,无论是对字段使用了函数还是值使用了函数都不走索引,解决办法通过应用程序计算好,将计算的结果传递给sql,而不是让数据库去计算

7901a6d3a5981f70b70b98359951338b.png
ca3f1f693ac1b804a5e8436b818f9a76.png

id是主键,id/10使用了算数表达式不走索引

23bbb40d0efe874c92b90f4f6f3fcc44.png

6. 查询时必须使用正确的数据类型

如果索引字段是字符串类型,那么查询条件的值必须使用引号,否则不走索引

1734e53975f3b8abba02758075c6de36.png

7. or 使用索引和不使用索引的情况

or 只有两边都有索引才走索引,如果都没有或者只有一个是不走索引的

10e1a4004b9ac888b159193178377a49.png

8. 用union少用or

尽量避免使用or,因为大部分or连接的两个条件同时都进行索引的情况几率比较小,应使用uninon代替,这样能走索引的走索引,不能走索引的就全表扫描。

5c23c78475d64a0fffb7ee13c3aac49d.png

9. 能用union all就不用union

union all 不去重复,union去重复,union使用了临时表,应尽量避免使用临时表

1d10d1e114ff26793e7bf3adad27cf0c.png

10. 复合索引

对于复合索引,如果单独使用右边的索引字段作为条件时不走索引的。即复合索引如果不满足最左原则leftmost不会走复合索引

266960290eeca3f638afc11e7a392b36.png

11. 覆盖索引

覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。

当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了(或覆盖了)满足查询结果的数据就叫做覆盖索引。

它包括在查询里的Select、Join和Where子句用到的所有列(即建索引的字段正好是覆盖查询条件中所涉及的字段,也即,索引包含了查询正在查找的数据)

覆盖索引:根据关键字就能够直接获取查询所需要的所有数据,不必要读取数据行的数据,所有数据是指where、select从句、order by、 group by从句的值

8c7bf71a1678c4be8dac3a4740fade0f.png

如果索引字段是字符串那么查询条件必须加引号,但是如果查询的列都在索引中,即使不满足走索引的条件,此时也会使用索引。示例中order_code=666666,是数字类型,没有加引号,按说是不走索引的,但是select * 而test表只有两个字段,id和order_code而这两个字段都创建了索引,这种情况也会走索引

ee999bdb605515d9523ba6737152a28a.png

12. order by

mysql有两种排序方式:

通过有序索引顺序扫描直接返回有序数据,通过explain分析显示Using Index,不需要额外的排序,操作效率比较高。

通过对返回数据进行排序,也就是Filesort排序,所有不是通过索引直接返回排序结果的都叫Filesort排序。Filesort是通过相应的排序算法将取得的数据在sort_buffer_size系统变量设置的内存排序中进行排序,如果内存装载不下,就会将磁盘上的数据进行分块,再对各个数据块进行排序,然后将各个块合并成有序的结果集

order by 使用索引的严格要求:

索引的顺序和order by子句的顺序完全一致

索引中所有列的方向(升续、降续)和order by 子句完全一致

当多表连接查询时order by中的字段必须在关联表中的第一张表中

如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合 索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。

正例:where a=? and b=? order by c; 索引:a_b_c

反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引 a_b 无法排序

2176974da99f256445ca3922edb41724.png

order by如果根据多个值进行排序,那么排序方式必须保持一致,要么同时升续,要么同时降续,排序方式不一致不走索引

7beca74d9d910946830b7e8d97f15181.png
38445a9b129a9b045999ff3de9890476.png

13. group by

默认情况下,group by column;有两个作用,第一个就是根据指定的列进行分组,第二作用group by 不但分组,而且还为分组中的数据按照列来排序,如果分组的字段创建了索引,那么排序也没什么毕竟排序走索引也很快

但是如果group by指定的列没有走索引,而我们通常情况下只对分组中的数据进行统计,例如对分组中的数据求和,通常顺序无关紧要,此时就要关闭group by 的排序功能,使用Order By NULL;来关闭排序功能,避免排序对性能的影响。

ed5b47c2f1337691341b88cc0cc5d0c0.png

14. 分页limit

分页查询一般会全表扫描,优化的目的应尽可能减少扫描;

第一种思路:在索引上完成排序分页的操作,最后根据主键关联回原表查询原来所需要的其他列。这种思路是使用覆盖索引尽快定位出需要的记录的id,覆盖索引效率高些

第二中思路:limit m,n 转换为 n

之前分页查询是传pageNo页码, pageSize分页数量,

当前页的最后一行对应的id即last_row_id,以及pageSize,这样先根据条件过滤掉last_row_id之前的数据,然后再去n挑记录,此种方式只能用于排序字段不重复唯一的列,如果用于重复的列,那么分页数据将不准确

当只一行数据使用limit 1

679d4a99c2534fa5b26792d3755ba30b.png
2f91b3f19bb5029d0972dadc15859f97.png

多表连接查询连接条件(也就是外键必须创建索引,否则大数据查询直接卡死)

4602a0f0849c44fdacad86dce63fc517.png

如果全表扫描比使用索引快,就不会使用索引,比如 表的数量很少或者满足条件的数据量比较大也不走索引, 查询数据库记录时,查询到的条目数尽量小,当通过索引获取到的数据库记录> 数据库总记录的1/3时,SQL将有可能直接全表扫描,索引就失去了应有的作用。

2e4d2a4528a9cbba1acca4602720fccd.png

where条件将能过滤掉多的条件写在前面,过滤掉少部分的数据写在后面,这样先排除一大部分不满足条件的数据,然后剩下一小部分数据,然后再从中找出满足条件的记录

70fc83fc31a67818fa759ce0869c5c3d.png

数据类型不匹配是不会走索引,例如对字符串类型创建索引,where条件值却没有使用引号,就不走索引,join语句中join条件字段类型不一致的时候MYSQL无法使用索引

15 in和exists

查询所有下过订单的用户(tbl_user 500w条数据,tbl_order 3条数据), 有两种方式,一种使用in另一种使用exists,但是两者效率相差很大

c061510342e819a4167855888e5486cc.png

in的伪代码:

fd4680e51a1c1a74678460c5a2a27365.png

SELECT * FROM A WHERE id IN (SELECT a_id FROM B) 当A表中的数据量远大于B表中的数据量时使用in

查询用户id大于10的用户的订单信息

7a3cb7adff1c684da0701b3a5cbf5a6a.png
ec6e6dd0bab253cacf963f0098c297e0.png

从以上逻辑可以看到exists每次循环一下外表都要查询一下内表,即使外表数量很少,但是每循环一次外表都要去查询一个大表,这样的效率是不高的,除非子查询走索引,最好走覆盖索引。

SELECT * FROM B o WHERE exists(SELECT 1 FROM A WHERE o.user_id > 10) 网上说当B表的数据量小A表的数据量很大时用exists。上面那个例子没有测试出来,实际优化时in和exists具体那个好根据具体执行情况来选择,也不能一味的就说某种情况下用这个就比那个快

16. 强制索引

当查询时不走索引时可以通过force index 强制mysql使用指定的索引,一般情况下如果mysql不走索引它是认为全表扫描会更快些,可以通过强制走索引看一下查询时间,如果强制索引效果更好,查询速度更快就使用强制索引,如果强制索引没有明显效果就没必要使用了。

mysql强制使用索引:force index(索引名或者主键PRI)

-- 强制使用主键索引

select * from table force index(PRI);

-- 强制使用索引"idx_xxx"

select * from table force index(idx_xxx);

-- 强制使用索引"PRI"和"idx_xxx"

select * from table force index(PRI,idx_xxx);

mysql禁止某个索引:ignore index(索引名或者主键PRI)

-- 禁止使用主键

select * from table ignore index(PRI)

-- 禁止使用索引"idx_xxx"

select * from table ignore index(idx_xxx);

-- 禁止使用索引"PRI","idx_xxx"

select * from table ignore index(PRI,idx_xxx);

六:其它优化

禁止使用select *,需要什么字段就去取哪些字段

超过三个表禁止join。需要join的字段数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。说明:即使双表 join 也要注意表索引、SQL 性能。尽可能避免复杂的join和子查询。尽量使用左右连接,少使用内连接。永远小结果集驱动大结果集(这点mysql会自动优化)

不要使用count(列名)或 count(常量)来替代 count(),count()是SQL92定义的标准统计行数的语法,跟数据库无关,跟 NULL和非NULL无关。说明:count(*)会统计值为NULL 的行,而count(列名)不会统计此列为NULL值的行。

不得使用外键与级联,一切外键概念必须在应用层解决。

禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。避免使用存储过程、触发器。

使用表连接来优化子查询。尽量避免使用子查询,建议将子查询转换成关联查询,子查询的效率并没有连接join查询快(并不绝对),连接查询之所以更有效率一些,是因为mysql不需要再内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作。对于多表连接,如果连接条件创建索引效率更高。

对于列类型是字符串,值必须使用单引号括住,如果没有引号引住就不走索引, 结论:字符串必须使用‘’引住

拒绝大SQL,拆分成小SQL

优先优化高并发的SQL,而不是执行频率低某些“大”SQL

在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

减少 IO 次数

IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当然,也是收效最明显的优化手段。

降低 CPU 计算

除了 IO 瓶颈之外,SQL优化中需要考虑的就是 CPU 运算量的优化了。order by, group by,distinct … 都是消耗 CPU 的大户(这些操作基本上都是 CPU 处理内存中的数据比较运算)。当我们的 IO 优化做到一定阶段之后,降低 CPU 计算也就成为了我们 SQL 优化的重要目标

大表的数据修改最好要分批处理,例如1000万行的记录删除更新 100万行记录,可以一次只删除更新5000行记录,暂停几秒,然后再执行剩下的数据。

如何修改大表的表结构:

先在从服务器上修改,然后将从服务器改为主服务器,然后再从主服务器上修改,然后再切换回来,此种方式需要切换主从,有一定的风险。

在主服务器上创建一张新表,将老表的数据迁移到新表,创建一个触发器,将老表的新数据同步到新表中,对老表加一个排它锁,重新命名新表和老表,然后删除掉老表(整个操作过程比较复杂,可以通过工具来实现)

读者福利:

马上又是新的一年的“金三银四”了,想沉淀学习,明年准备跳槽的朋友们一定需要全面的面试资料和进阶学习渠道,小编这里有专门整理的java面试集锦,关注私信小编回复“资料”即可获得免费领取方式~

8ef622e220c4e38da8122eb27cc6029f.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/543414.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用CoreImage教程

使用CoreImage教程 CoreImage包含有很多实用的滤镜,专业处理图片的库,为了能看到各种渲染效果,请使用如下图片素材. 现在可以开始教程了: #define FIX_IMAGE(image) fixImageWidth(image, 320.f)// 固定图片的宽度 UIImage * fixImageWidth(UIImage *image, CGFloat width) {f…

电脑生成siri语音_米家智能台灯1S全新升级,支持小爱和Siri的语音控制

夜晚的灯光是我们最为需要的东西&#xff0c;但很多时候&#xff0c;我们需要灯照在不同的地方&#xff0c;平时我只靠吸顶灯的光来照亮家里的每一个角落&#xff0c;甚至是看书的时候都只靠吸顶灯照明。台灯作为占用面积小&#xff0c;光照均匀&#xff0c;让很多的人越来越依…

linux vnc检查,检查Ubuntu VNC设置(避免远程登陆)

(1)安装x11vncsudo apt-get install x11vnc(2)将x11vnc加入xinetdsudo gedit /etc/xinetd.d/x11vnc加入下面这段service x11vnc{ port 5900 type UNLISTED socket_type stream protocol tcp wait …

JavaScript网络地址作为参数_JavaScript之bind的模拟实现

阅读本文约需要5分钟大家好&#xff0c;我是你们的导师&#xff0c;我每天都会给大家分享一些干货内容(当然了&#xff0c;周末也要允许老师休息一下哈)。昨天给大家分享了JavaScript的call和apply的模拟实现&#xff0c;今天给大家分享一下bind的模拟实现。什么是bind&#xf…

cdh集群linux命令,CDH集群中,服务器启动spark2-shell命令行注意事项

1、环境cdh5.12.3spark2 2.3.02、需要本地地洞spark2-shell用于环境测试错误一&#xff1a;Error: A JNI error has occurred, please check your installation and try againException in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Loggerat java.l…

python语音转文字软件_python编写语音转文字软件|语音转文字工具免费版下载(语音批量转换文字) v2.0 最新版_数码资源网...

没有专业的工具怎么能够将语音转换为文字呢&#xff1f;小编为大家提供了语音转文字工具免费版&#xff0c;一款通过Python编写语音转文字软件。用户通过使用语音转文字工具免费版&#xff0c;可以将语音批量转换文字&#xff0c;而且操作也是非常的简单&#xff0c;如果你需要…

Spring-bean作用域scope详解

2019独角兽企业重金招聘Python工程师标准>>> 默认情况下&#xff0c;从bean工厂所取得的实例为Singleton&#xff08;bean的singleton属性&#xff09; Singleton: Spring容器只存在一个共享的bean实例&#xff0c;是默认的配置。 Prototype: 每次对bean的请求都会创…

c语言怎么写星星代码,C语言打印星星的问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #include int main(void){int index, up, lines;printf("请输入将要显示的行数:\n");while(scanf("%d", &up) 1){if(up % 2 0){for(lines 1; lines < up / 2; lines){for(index 0; index …

c语言计算机猜数字100以内,求一个猜数字C语言代码,要求如下 计算机生成一个100以内的随机数,玩家来猜 记录猜的次数,最后打...

满意答案itpotato推荐于 2017.10.09采纳率&#xff1a;51% 等级&#xff1a;12已帮助&#xff1a;4600人/**百度知道越来越水了&#xff0c;这么简单的题就一个回答*没见过限定头文件数目的。。而且是限定至少。。。。*/#include#include#include#includeint getrand(){sran…

fakeapp2.2.0下载_软件下载 | SuperCuger 测量平差系统 V1.0

SuperCuger测量平差系统 version 1.0 是一款基于测绘工程中边角网、测角网、测边网、水准网测量数据的免费开源的可视化平差系统。可用于测绘工程中测量平差计算和平差结果报告生成&#xff0c;和插件(中间件)模式扩展新的平差功能。我们的软件具备平差数据可视化&#xff0c;便…

c语言cin输入数组,C++基础:各种输入方法总结cin.get()、

原标题&#xff1a;C基础&#xff1a;各种输入方法总结cin.get()、在C中&#xff0c;各种输入方法还是不少的&#xff0c;而且各有所异&#xff0c;本文做一点简要总结&#xff0c;主要涉及如下内容&#xff1a;cin、cin.get()、cin.getline()、getline()、gets()、getchar()。…

手机怎么能把书签导出来_成人高考能在手机上报名吗?成人高考怎么缴费?

很多成人高考的考生在报名考试的时候想用手机进行报名&#xff0c;但是听说都是使用电脑报名&#xff0c;所以不知道手机报名行不行&#xff0c;另外还有很多考生也不知道如何缴费。那么成人高考能在手机上报名吗?成人高考怎么缴费?下面小编就来和大家聊一聊成人高考手机报名…

thinkphp单入口和多入口的访问方法

完全是参考thinkphp的官网资料 现在, 基本上都是 用 单入口 的方式来做的! thinkphp可创建多入口和单入口两种模式&#xff0c;本文主要讲解创建方法和两者的区别。 TP版本&#xff1a;3.1.3 前端&#xff1a;Home&#xff0c;后台&#xff1a;Admin 一. 创建方法 单入口&#…

财务模块的一些基础概念

财务会计承担着企业总体信息管理和传递的职能&#xff0c;无论企业采用何种运营模式、经营何种业务&#xff0c;都离不开财务的支持&#xff0c;大多数运营和管理流程均与财务存在着接口&#xff0c;为此&#xff0c;优化、高效的财务运作模式和流程成为确保企业良性发展和业务…

if mybatis tk 多个_面试题:mybatis 中的 DAO 接口和 XML 文件里的 SQL 是如何建立关系的?...

前言这是 mybatis 比较常问到的面试题&#xff0c;我自己在以前的面试过程中被问到了2次&#xff0c;2次都是非常重要的面试环节&#xff0c;因此自己印象很深刻。这个题目我很早就深入学习了&#xff0c;但是一直没有整理出来&#xff0c;刚好最近一段时间由于工作太忙&#x…

多机器使用setnx 设置同一个key_Redisson分布式锁的简单使用

做一个积极的人编码、改bug、提升自己我有一个乐园&#xff0c;面向编程&#xff0c;春暖花开&#xff01;一&#xff1a;前言我在实际环境中遇到了这样一种问题&#xff0c;分布式生成id的问题&#xff01;因为业务逻辑的问题&#xff0c;我有个生成id的方法&#xff0c;是根据…

孟德尔随机化周报 (12.14)

欢迎报名2023年郑老师团队课程&#xff01; 郑老师科研统计培训&#xff0c;包括临床数据、公共数据分析课程等&#xff0c;欢迎报名 孟德尔随机化,Mendilian Randomization&#xff0c;简写为MR&#xff0c;是一种在流行病学领域应用广泛的一种实验设计方法&#xff0c;利用公…

android计算器弹窗,android实现简易计算器

本文实例为大家分享了android实现简易计算器展示的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下效果图&#xff1a;一、如图&#xff0c;首先布局计算器主页显示activity_main.xmlxmlns:tools"http://schemas.android.com/tools"android:layout_width&qu…

多选取值_机制砂如何控制MB值和石粉含量

随着环保政策的加强和河沙采挖禁令的收紧&#xff0c;机制砂逐渐成为建筑用砂的主流。但很多砂石厂生产设备落后、生产条件简陋、生产工艺不完善导致生产的机制砂品质低&#xff0c;质量不能满足高等级混凝土的要求。不仅卖不上价格&#xff0c;还浪费了矿石资源&#xff0c;挣…

python爬虫哪个选择器好用_Python网络爬虫四大选择器用法原理总结

前几天小编连续写了四篇关于Python选择器的文章&#xff0c;分别用正则表达式、BeautifulSoup、Xpath、CSS选择器分别抓取京东网的商品信息。今天小编来给大家总结一下这四个选择器&#xff0c;让大家更加深刻的理解和熟悉Python选择器。 一、正则表达式 正则表达式为我们提供了…