Mysql优化

一.表结构优化
二.列类型优化
三.索引优化策略
四.聚簇索引和非聚簇索引
五.理想的索引

怎么查看一个sql语句的执行效果

    在sql语句前面加上 “explain”,如果加上"\\\\G",则能看到竖列效果   explain  sql   \\\\G    
    结果中的 key_len 就是在查询上所用到的索引的个数; using filesort就是用到了排序的意思;using index是用到了索引覆盖
    排序非常耗资源,想分组,必须排序
    测试运行需要的时间   time  file.php
    如果A\\\\B两张表结构是一样的,把A表里面的数据插入B表,
    可以这样执行:insert into B select * from A;
    如果要插入某个字段的数据
    insert into B select id,name,age from A;

   在数据库终端指令, 如果要查看前几个 sql语句运行时间,show profiles;这个时候只能看到小数点后两位,
    如果要看到精确的运行时间。set profiling = on;
    如果某个表查询的时候出现了乱码,在终端 set names utf8;
    delimiter $   //在终端输入$才会结束一条语句

优化总则
1.少查(能不查就不查)
2.查少(少查点数据)
3.快点查(走索引)
4.少排序

一.表结构优化

1.定长和变长分离

  如id int,占4个字节,char(4)占4个字段长度,也是定长,time 即每一个单元值占的字节是固定的
  而varchar,text,blob,这种变长字段,适合单放一张表,用主键与核心表关联起来

2.常用字段和不常用字段分表,通过uuid将两张表关联。这个需要结合网站的具体业务来分析,分析字段的查询场景,查询频率低的字段,单拆出来(用空间来换取时间)

    比如两张关联表,一个是板块表(cat),另一个是板块下回复的帖子。查询某个板块下有多少个回复
    方法一:先查出有几个板块,再在for循环里面找每个板块下有多少回复
    select * from cat;  //比如10个板块
    for($i=1; $i<=10; $i++){
      select count(*) from post where cat_id = $i;
    }
    方法二,使用左右连接查询,比较消耗资源,不推荐
    select cat.* from cat left join post on cat.cat_id = post.cat_id group by cat_id;
    如果我们需要实时计算帖子的数量,可以在cat表里面再加一个num字段,每次有人发帖,让这个字段用update更新加1,这是最好的方法。

二.列类型优化

字段类型选择原则
整型>date,time,>enum,char>varchar>blob,text

    列的特点分析:
    整型:定长,没有国家/地区之分,没有字符集的差异
    比如,tinyint 1,2,3,4,5 <--> char(1) a,b,c,d
    从空间上,都是占1个字节,但是order by排序,前者快
    原因:char需要考虑字符集与校对级(就是排序规则)
    time 定长,运算快,节省空间,考虑时区时,写sql时不方便 where > '2016-10-11';
    enum:定长,能起约束的目的,内部用整型来存储,但与char联查时,内部要经历串与值得转化
    Char 定长,考虑字符集的转换与排序时的校对集
    varchar,不定长,要考虑字符集的转换与排序时的校对集,速度慢
    text/blob,无法使用内存临时表(排序等操作只能在磁盘上进行)

三.索引优化策略

1.索引类型
1.1Btree索引(二叉树就是索引)--适用于范围的查询

    名叫btree索引,大的方面看,都是用的平衡树,但是具体的实现上,各引擎稍有不同
    比如,严格说NDB引擎,使用的是T-tree
    Mysiam,innodb中默认使用B-tree
    但抽象一下,B-tree系统可以理解为"排好序的快速查找结构"

1.2hash索引(只在内存表里面使用hash索引)

    在memory表里默认是hash索引,hash里的理论查询时间复杂度为0(1)(一次就能找到)
    hash的特点:
    1.随机性:hash函数计算后的结果,是随机的,如果是在磁盘上放置数据,
      比如主键为id,那么随着id的增长,id对应的行,在磁盘上随机放置
    2.无法对范围查询进行优化
    3.(离散性)无法利用前缀索引,比如在btree中,field列的值"helloworld",加索引, hash(helloworld)和hash(hello),两者没有关系。
    4.排序也法优化(它是随机分配数据的)
    5.必须回行,也就是说,通过索引拿到数据位置,必须回到表中取数据

2.btree索引常见的误区

    要查询的字段都建立了索引,并不是都可以使用得到。查询的时候遵循左前缀规则

2.索引的左前缀规则--比如index(a,b,c)

语句 索引是否发挥作用
where a=3 是,只使用了a列
where a=3 and b=5 是,只用了a,b列
where a=3 and b=5 and c=4 是,使用了abc列
where b=3 / where c=4
where a=3 and c=4 a列能发挥索引,c不能
where a=3 and b>10 and c=7 A能利用,b能利用,c不能利用
同上,where a=3 and b like"xxx%" and c=7 A能利用,b能利用,c不能利用

四.聚簇索引和非聚簇索引

Myisam用的是非聚簇索引:主键和次索引都指向物理行磁盘的位置

    数据是数据 独立文件 xx.myd
    索引是索引 独立文件 xx.myi
    两者不掺和 这就是非聚簇
    它的查找是先根据索引查找到主键的值,值旁边有一个地址,在地址上去查找你要的信息,这个过程叫“回行”。
    但是innodb聚簇,值得旁边直接就是行信息。这就是他们的本质信息

innodb用的是聚簇索引:innodb的主索引文件上,直接存放该行数据,称为聚簇索引,次索引指向对主键的作用

    注意:对innodb来说
    1.主键索引  既存储索引,又在叶子中存储行的数据
    2.如果没有主键(primary key),则会unique key做主键
    3.如果没有unique,则系统生成一个内部的 rowid 做主键
    4.像innodb中,主键的索引结构中,既存储了主键的值,又存储了行数据,这种结构称为"聚簇索引"

聚簇索引
优势:根据主键查询条目比较少时,不用回行(数据就在主节点下)
劣势:如果碰到不规则数据插入时,造成频繁的页分裂

索引覆盖
索引文件中,myi有你需要的字段,就不需要回行。这就是索引覆盖

    explain sql \\\\G   如果在extra里面出现了"using index",就是用了索引覆盖,查询效率会很高
    比如:如果表A中c1建立了索引
    explain select c1 from A where c1>5 \\\\G;  这个时候就用到了索引覆盖
      explain select c1,c2 from A where c1>5 \\\\G;如果c2没有索引  这个时候没用索引覆盖。因为c2在索引里面找不到,需要回行

五.理想的索引

     1. sql查询中也可以直接使用函数,例如查询词典表中最长的两个单词:
    select  * from dict order by length(word) desc limit 2;

    2.取10个,单词的左边只有一个值的:
    select   left(word,1)  from dict limit 10;
    3.取重复的
    select  distinct left(word,1)  from dict limit 10;
    select count( distinct left(word,1) ) from dict;

2.伪哈希索引技巧
用于存储url,有两种方法。1,列内容倒过来存储并建立索引。这样左前缀区分度大。

    2.伪hash索引效果同时存url hash列
    create table A( id int primary key,
            url char(60) not null default '' );
    insert into A values(1,"www.baidu.com"),
    (2,"www.sina.com"),(3,"www.itxdl.com");
    alert table A add urlcrc int unsigned not null;

    在sql存储时,crccurl == crc32(url)
    因为crc的结果是32位,int 无符号数,因此当数据超过40亿也会有重复,但这是是的的。(索引长度为int4个字节)
    select crc32('str');  //可以把任何字符串转换成数字

    商品建立索引,一般两种方式
    以,栏目、价格 index(cat_id, price); 或者栏目、品牌、价格 index(cat_id,brand_id,shop_price);

索引与排序有两种情况
1.对于覆盖索引,直接在索引上查询时,就是有序的,using,index
在innodb引擎中,沿着索引字段排序,也是自然有序的,对于myisam引擎,如果按某种索引字段排序,如id,但去除的字段中未有索引字段,如goods_name,myisam的做法,不是 索引->回行,而是先去除所有的行,再进行排序
2.先去除数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能在内存中)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容