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 where num=@num
建议改为强制查询使用索引:--->  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.客户端返回大数据量
尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
 
 
 

MYSQl 全表扫描以及查询性能的更多相关文章

  1. Facebook对MySQL全表扫描性能的改进

    原文博客如下: http://yoshinorimatsunobu.blogspot.com/2013/10/making-full-table-scan-10x-faster-in.html 如下是 ...

  2. 造成MySQL全表扫描的原因

    全表扫描是数据库搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止.通常在数据库中,对无索引的表进行查询一般称为全表扫描:然而有时候我们即便添加了索引,但当我们的SQL语句写的不合理的时候也 ...

  3. mysql 全表扫描、全索引扫描、索引覆盖(覆盖索引)

    full index scan:全索引扫描,查询时,遍历索引树来获取数据行.如果数据不是密集的会产生随机IO 在执行计划中是Type列,index full table scan:通过读物理表获取数据 ...

  4. mysql 全表扫描场景

    全表扫描是数据库搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止.通常在数据库中,对无索引的表进行查询一般称为全表扫描:然而有时候我们即便添加了索引,但当我们的SQL语句写的不合理的时候也 ...

  5. MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析

    文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...

  6. MySql避免全表扫描【转】

    原文地址:http://blog.163.com/ksm19870304@126/blog/static/37455233201251901943705/ 对查询进行优化,应尽量避免全表扫描,首先应考 ...

  7. Mysql避免全表扫描sql查询优化 .

    对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: ·   使用ANALYZE TABLE tbl_n ...

  8. MySql避免全表扫描

    对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: · 使用ANALYZE TABLE tbl_name为 ...

  9. Mysql怎么样避免全表扫描,sql查询优化

    对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引: 尝试下面的技巧以避免优化器错选了表扫描: 使用ANALYZE TABLE tbl_name为扫 ...

随机推荐

  1. Docker的简介以及Dockerfile编写与使用

    Docker的简介 Docker是在容器的基础上,进行了进一步的封装,极大的简化了容器的创建和维护.使得Docker技术比虚拟机技术更为轻便.快捷. 下面是两张对比图. 可以看到传统虚拟机技术是虚拟出 ...

  2. java文件中出现最多的前n个单词

    将文件打开,之后每读入一次,最后按空格进行分割.存入到map里面之后进行相应的比较输出操作.并将相应的内容输出到文件里面. package com.keshangone; //将想要输出的数据写入新的 ...

  3. (js描述的)数据结构[队列结构,优先级队列](3)

    (js描述的)数据结构[队列结构](3) 一.队列结构的特点: 1.基于数组来实现,的一种受限的线性结构. 2.只允许在表头进行删除操作,在表尾进行插入操作. 3.先进先出(FIFO) 二.队列的一些 ...

  4. css怪异盒模型和弹性盒布局(flex)详解及其案例

    一.怪异盒模型 怪异盒模型的属性是box-sizing,他有两个属性值: 1.content-box 这是由 CSS2.1 规定的宽度高度行为.宽度和高度分别应用到元素的内容框.在宽度和高度之外绘制元 ...

  5. matplotlib BlendedGenericTransform(混合变换)和CompositeGenericTransform(复合变换)

    2020-04-10 23:31:13 -- Edit by yangrayBlendedGenericTransform是Transform的子类,支持在x / y方向上使用不同的变换.(博主翻译为 ...

  6. 条件变量 condition_variable wait_for

    wait_for(阻塞当前线程,直到条件变量被唤醒,或到指定时限时长后) #include <iostream> #include <atomic> #include < ...

  7. Java课程设计之——Web前端

    主要使用的技术 Javascript/JQuery html css Jsp 前期调查 能看到的网页大致可以分为两个部分,一个是搜索的首页index.html,一个是搜索结果页/s index.htm ...

  8. ASE课程总结 by 朱玉影

    收获: 最大的收获应该就是对待选题要慎重吧,虽然前期做了一下调研,但是还是不够,所以到最后我们的项目才会不能公开发布,项目中间也是波折不断,导致我们走了很多弯路,浪费了很多时间吧.选题一定要慎重,慎重 ...

  9. sqli-labs通关教程----41~50关

    第四十关 与前几关一样,闭合变成') 插入数据 ?id=1') ;insert into users(id,username,password) values('17','aaa','bbb'); % ...

  10. cwyth(自动核销代码)

    财务一体化系统,自动核销大数据代码: import pymysql import random import time #指定数据库地址.用户.密码.端口,使用connect()方法声明一个Mysql ...