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为扫 ...
随机推荐
- node实现防盗链
什么是防盗链 盗链,顾名思义就是盗窃链接,就是在他人未经允许的情况下,去使用他人站点的任何图片,视频,内容等资源,来借此提升已用的站点的活跃度,严重损坏了别人的利益.那么防盗链就是采用一些办法阻止自己 ...
- Node.js 的事件循环机制
目录 微任务 事件循环机制 setImmediate.setTimeout/setInterval 和 process.nextTick 执行时机对比 实例分析 参考 1.微任务 在谈论Node的事件 ...
- 360众测考试,weblogic题(CVE-2018-2894)文件上传漏洞
0x01 漏洞简介 Weblogic管理端未授权的两个页面存在任意上传jsp文件漏洞,进而获取服务器权限. Oracle 7月更新中,修复了Weblogic Web Service Test Page ...
- 【python实现卷积神经网络】上采样层upSampling2D实现
代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...
- 端口扫描工具nmap的常用参数讲解
转载请注明出处:https://www.cnblogs.com/wangyanzhong123/p/12576406.html nmap下载与安装 这个没什么好说的.很简单官网上下载就ok了,需要注意 ...
- Java匹马行天下之JavaSE核心技术——异常处理
Java匹马行天下之JavaSE核心技术——异常处理 异常的简介 在Java中,异常就是Java在编译.运行或运行过程中出现的错误. 程序错误分为三种:编译错误.运行时错误和逻辑错误 编译错误是因为程 ...
- mysql datetime类型 按格式在页面输出
mysql datetime类型对应java Date类型 java.util.Date类型会显示时间戳 java.sql.Date 只显示年月日不显示时分秒 只需要重写get方法 就能按格式输出 ...
- vue2.x学习笔记(十七)
接着前面的内容:https://www.cnblogs.com/yanggb/p/12616847.html. 动态组件&异步组件 在前面学习组件基础的时候学习过动态组件,官方文档给出过一个例 ...
- 详解 List接口
本篇博文所讲解的这两个类,都是泛型类(关于泛型,本人在之前的博文中提到过),我们在学习C语言时,对于数据的存储,用的差不多都是数组和链表. 但是,在Java中,链表就相对地失去了它的存在价值,因为Ja ...
- 虎符ctf-MISC-奇怪的组织(看完官方题解,找到了)
一道取证题,一整场比赛,基本就死磕了这一题 写的很乱,因为当时的思维就是那么乱,完全没有注意到出题人的提示, 还没做出来,没有找到关键key 那个人的real name 文档:虎符.note链接:ht ...