震惊,竟然不能命中索引?

前言

数据库查询不走索引会导致全表扫描,效率低下。

举例

  1. “列类型”与“where值类型”不符,不能命中索引,会导致全表扫描(full table scan)。
  • 数据准备
create table t1 (
cell varchar(3) primary key
)engine=innodb default charset=utf8;

insert into t1(cell) values ('111'),('222'),('333');
cell属性为varchar类型;
cell为主键,即聚簇索引(clustered index);
  • 测试语句
explain select * from t1 where cell=111;
explain select * from t1 where cell='111';
第一个语句,where后的值类型是整数(与表cell类型不符);
第二个语句,where后的值类型是字符串(与表cell类型一致);
  • 测试结果


    列类型与where后值类型不符.png

    列类型与where后值类型相同.png

    强制类型转换,不能命中索引,需要全表扫描,即3条记录;
    类型相同,命中索引,1条记录;

  1. 相join的两个表的字符编码不同,不能命中索引,会导致笛卡尔积的循环计算(nested loop)
create table t2 (
cell varchar(3) primary key
)engine=innodb default charset=latin1;

insert into t2(cell) values ('111'),('222'),('333'),('444'),('555'),('666');

create table t3 (
cell varchar(3) primary key
)engine=innodb default charset=utf8;

insert into t3(cell) values ('111'),('222'),('333'),('444'),('555'),('666');
t2和t1字符集不同,插入6条测试数据;
t3和t1字符集相同,也插入6条测试数据;
  • 测试语句
explain select * from t1,t2 where t1.cell=t2.cell;
explain select * from t1,t3 where t1.cell=t3.cell;
第一个join,连表t1和t2(字符集不同),关联属性是cell;
第一个join,连表t1和t3(字符集相同),关联属性是cell;
  • 测试结果


    字符编码不同.png

    字符编码相同.png

    t1和t2字符集不同,存储空间不同;
    t1和t2相join时,遍历了t1的所有记录3条,t1的每一条记录又要遍历t2的所有记录6条,实际进行了笛卡尔积循环计算(nested loop),索引无效;
    t1和t3相join时,遍历了t1的所有记录3条,t1的每一条记录使用t3索引,即扫描1行记录;

explain

  • type访问类型,即找到所需数据使用的遍历方式,潜在的方式有:
    ALL(Full Table Scan):全表扫描;
    index:走索引的全表扫描;
    range:命中where子句的范围索引扫描;
    ref/eq_ref:非唯一索引/唯一索引单值扫描;
    const/system:常量扫描;
    NULL:不用访问表;
    ALL最慢,逐步变快,NULL最快。
  • Extra字段,对分析与优化SQL有很大的帮助
  1. Using where
    Extra为Using where说明,SQL使用了where条件过滤数据
    需要注意的是:
    (1)返回所有记录的SQL,不使用where条件过滤数据,大概率不符合预期,对于这类SQL往往需要进行优化;
    (2)使用了where条件的SQL,并不代表不需要优化,往往需要配合explain结果中的type(连接类型)来综合判断;
    (3)常见的优化方法为,在where过滤属性上添加索引。
  2. Using index
    Extra为Using index说明,SQL所需要返回的所有列数据均在一棵索引树上,而无需访问实际的行记录。
    这类SQL语句往往性能较好。
  3. Using index condition
    Extra为Using index condition说明,确实命中了索引,但不是所有的列数据都在索引树上,还需要访问实际的行记录。
  4. Using filesort
    Extra为Using filesort说明,得到所需结果集,需要对所有记录进行文件排序。
    这类SQL语句性能极差,需要进行优化。
    在一个没有建立索引的列上进行了order by,就会触发filesort,常见的优化方案是,在order by的列上添加索引,避免每次查询都全量排序。
  5. Using temporary
    Extra为Using temporary说明,需要建立临时表(temporary table)来暂存中间结果。
    这类SQL语句性能较低,往往也需要进行优化。
    group by和order by同时存在,且作用于不同的字段时,就会建立临时表,以便计算出最终的结果集。
  6. Using join buffer (Block Nested Loop)
    Extra为Using join buffer (Block Nested Loop)说明,需要进行嵌套循环计算。
    这类SQL语句性能往往也较低,需要进行优化。
    两个关联表join,关联字段均未建立索引,就会出现这种情况。常见的优化方案是,在关联字段上添加索引,避免每次嵌套循环计算。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容

  • --- layout: post title: "如果有人问你关系型数据库的原理,叫他看这篇文章(转)" date...
    蓝坠星阅读 790评论 0 3
  • MySQL技术内幕:SQL编程 姜承尧 第1章 SQL编程 >> B是由MySQL创始人之一Monty分支的一个版...
    沉默剑士阅读 2,428评论 0 3
  • 常用语句: sql/plus sqlplus 'amdocs/Amdocs.Jx.China.110#@ysdb1...
    好好学习的蜗牛阅读 3,008评论 0 0
  • 原文《MySQL实战45讲》 前言 ​ 在实际生产中,关于 join 语句使用的问题,一般会集中在以下两类: ...
    灰气球阅读 1,642评论 0 0
  • 牛顿, 卡塞格林,消除球差,镜片是非球面,倒像 格雷戈里,主镜抛物面,副镜面椭球型,正像! 内史密斯,是卡塞格林加...
    张宝兴阅读 299评论 0 0