MYSQl 全表扫描以及查询性能
-- 本文章仅用于学习,记录
一. Mysql在一些情况下全表检索比索引查询更快:
1.表格数据很少,使用全表检索会比使用索引检索更快。一般当表格总数据小于10行并且数据行的长度非常小的时候会使用全表检索;
2.在ON或者WHERE中,没有使用索引列作为查询条件;
3.使用了索引列与一个常量进行比较,但是mysql发现该索引列覆盖的数据太大,反而全表检索更快(一般当索引列覆盖的数据大于全表数据的30%时,会触发mysql使用全表检索);
4.使用了一个覆盖了大部分数据的索引列与另外表的列进行关联查询,此时mysql会使用全表检索。
二. 可能造成mysql 全表扫描的原因/查询性能差:
01. 使用null做为判断条件
如:select store from flowers where name = null;
建议在设计字段时尽量将字段的默认值设为0,改为select account where nickname = 0;
02. 左模糊查询Like %XXX%
如:select store from flowers where name like ‘%XXX%’ 或者 select store from flowers where name like ‘%XXX’
建议使用select store from flowers where name like ‘XXX%’,如果必须要用到做查询,需要评估对当前表全表扫描造成的后果;
03. 使用or做为连接条件
如:select store from flowers where id = 1 or id = 2;
建议使用union all,改为 select store from flowers where id = 1 union all select store from flowers where id = 2;
04. 使用in时(not in)
很多时候用 exists 代替 in 是一个好的选择。
如:select store from flowers where id in (1,2,3)
如果是连续数据,可以改为select store where id between 1 and 3;当数据较少时也可以参考union用法;
或者:select store from flowers where id in (select store_id from stores where id = 3 ),可以改为select store from flowers where id exsits (select store_id from stores where id = 3)
not in 可以对应 not exists;
05.使用!=或<>时
建议使用 <,<=,=,>,>=,between等;
06.对字段有操作时也会引起权标索引
如select amount from stores where salary * 0.8 = 1000 或者 select name from stores where sustring(title,1,3) = ‘daffodils’;
应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
建议改为: ---> select id from t where num=100*2
不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
07.使用count(*)时
如select count(*) from member
建议改为:---> select count(1) from member;
08.使用参数做为查询条件时
如果在 where 子句中使用参数,也会导致全表扫描。
因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项
建议改为强制查询使用索引:---> select id from t with(index(索引名)) where
num=@num
09.使用手动创建的临时表
建议使用联合(UNION / UNION ALL)来代替手动创建的临时表
当我们可以确认不可能出现重复结果集或者不在乎重复结果集的时候尽量使用union all而不是union ,因为union 和union all 的差异主要是前者需要将两个或者多个结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的cpu运算,增加资源消耗及延迟。
10.使用子查询
子查询内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查表t2,当外表的数据很大时,查询速度会非常慢。
建议使用连接(JOIN) 来代替子查询,MYSQl 不需要在内存中创建临时表来完成这个逻辑上需要两个表的查询工作。另外:如果你的应用程序有很多JOIN 查询,你应该确认JOIN 的字段是被建立过索引的。这样MYSQL 内部会启动为你优化JOIN 的sql 语句的机制。而且这些被用来JOIN的字段,应该是相同的类型的。例如:如果你要把DECIMAL 字段和一个INT 字段JOIN在一起,MYSQL 就无法使用他们的索引。对于那些STRING类型,还需要有相同的字符集才行。
11.使用函数索引
比如:select * from t where year(d)>= 2016
由于mysql 不像oracle 那样支持函数索引,也会直接全表扫描。
应改为---> select * from t where d>= '2016-01-01';
12.分组统计使用排序
分组统计可以禁止排序,避免不必要的order by 排序
比如 select name,sum(amount) as total_score from t group by name order by total_score
应改为---> select name,sum(amount) as total_score from t group by name
13.更新 clustered 索引数据列
应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
14.数值信息的字段设计为字符型
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
15.不合理的字段类型
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
16.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
17.使用游标
尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
18.大事务操作
尽量避免大事务操作,提高系统并发能力。
19.客户端返回大数据量
尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
- Facebook对MySQL全表扫描性能的改进
原文博客如下: http://yoshinorimatsunobu.blogspot.com/2013/10/making-full-table-scan-10x-faster-in.html 如下是 ...
- 造成MySQL全表扫描的原因
全表扫描是数据库搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止.通常在数据库中,对无索引的表进行查询一般称为全表扫描:然而有时候我们即便添加了索引,但当我们的SQL语句写的不合理的时候也 ...
- mysql 全表扫描、全索引扫描、索引覆盖(覆盖索引)
full index scan:全索引扫描,查询时,遍历索引树来获取数据行.如果数据不是密集的会产生随机IO 在执行计划中是Type列,index full table scan:通过读物理表获取数据 ...
- mysql 全表扫描场景
全表扫描是数据库搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止.通常在数据库中,对无索引的表进行查询一般称为全表扫描:然而有时候我们即便添加了索引,但当我们的SQL语句写的不合理的时候也 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- MySql避免全表扫描【转】
原文地址:http://blog.163.com/ksm19870304@126/blog/static/37455233201251901943705/ 对查询进行优化,应尽量避免全表扫描,首先应考 ...
- Mysql避免全表扫描sql查询优化 .
对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: · 使用ANALYZE TABLE tbl_n ...
- MySql避免全表扫描
对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: · 使用ANALYZE TABLE tbl_name为 ...
- Mysql怎么样避免全表扫描,sql查询优化
对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引: 尝试下面的技巧以避免优化器错选了表扫描: 使用ANALYZE TABLE tbl_name为扫 ...
随机推荐
- 微信小程序中使用template
当我们的项目需要多次使用同一个布局和样式的时候,我们就可以考虑使用template(模块)来减少冗余的代码. 使用方法: 1. 新建一个template文件夹存放通用模板: 2. 在文件夹汇里面新建一 ...
- python图片拼接
python图片拼接 这两天看到一张图片,想用python来实现类似的图片拼接 先分析图片: 很明显,这张图片是由多张图片叠加拼接而成 从最后一张开始开始叠加,之后的每张图片都往上平移了一个固定的距 ...
- 2017蓝桥杯算式900(C++C组)
题目:算式900 小明的作业本上有道思考题: 看下面的算式: (□□□□-□□□□)*□□=900 其中的小方块代表0~9的数字,这10个方块刚好包含了0~9中的所有数字. 注意:0不能作为某 ...
- 37.2 net-- tcp传输 ServerSocket、Socket
一.打开server端 package day35_net_网络编程.tcp传输; import java.io.IOException; import java.io.InputStream; im ...
- search(4)- elastic4s-ElasticDsl
上次分析了一下elastic4s的运算框架.本来计划接着开始实质的函数调用示范,不过看过了Elastic4s的所有使用说明文档后感觉还是走的快了一点.主要原因是elasticsearch在7.0后有了 ...
- 条件变量 condition_variable wait_for
wait_for(阻塞当前线程,直到条件变量被唤醒,或到指定时限时长后) #include <iostream> #include <atomic> #include < ...
- MAC 系统java开发环境搭建教程
1.在安装JDK之前,先查看下自己电脑是否已经安装了JDK. 打开终端,输入java -version并回车. 从上图中可以看出我们已安装了,JDK 8.如果这个版本是你需要的版本,可直接看4 ...
- git撤销已经push到远端的commit
在使用git时,push到远端后发现commit了多余的文件,或者希望能够回退到以前的版本. 先在本地回退到相应的版本: git reset --hard <版本号> // 注意使用 -- ...
- Pytest系列(21)- allure的特性,@allure.description()、@allure.title()的详细使用
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 前面介绍了两种allure的 ...
- Salesforce 学习 | 官方总结最实用的Spring '20新功能
在Spring '20正式发布之前,Trailblazers 社区举行了一个名为Treasure Hunt的在线活动,通过预览沙盒,分享他们认为Spring ‘20中最重要的功能.这篇文章就来盘点一下 ...