设为首页 收藏本站
查看: 974|回复: 0

[经验分享] MySQL建立索引的基础规则

[复制链接]

尚未签到

发表于 2018-10-1 14:56:00 | 显示全部楼层 |阅读模式
  1、mysql索引(基础与规则)
  索引规则:
  一、 MySQL建表,字段需设置为非空,需设置字段默认值。
  二、 MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL。
  三、 MySQL建表,如果字段等价于外键,应在该字段加索引。
  四、 MySQL建表,不同表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,否则无法正确使用索引进行关联对比。
  五、 MySQL使用时,一条SQL语句只能使用一个表的一个索引。所有的字段类型都可以索引,多列索引的属性最多15个。
  六、 如果可以在多个索引中进行选择,MySQL通常使用找到最少行的索引,索引唯一值最高的索引。
  七、 建立索引index(part1,part2,part3),相当于建立了index(part1),index(part1,part2)和index(part1,part2,part3)三个索引。
  八、 MySQL针对like语法必须如下格式才使用索引:SELECT * FROM t1    WHERE key_col LIKE 'ab%' ;
  九、 SELECT COUNT(*) 语法在没有where条件的语句中执行效率没有SELECT COUNT(col_name)快,但是在有where条件的语句中执行效率要快。
  十、 在where条件中多个and的条件中,必须都是一个多列索引的key_part属性而且必须包含key_part1。各自单一索引的话,只使用遍历最少行的那个索引。
  十一、 在where条件中多个or的条件中,每一个条件,都必须是一个有效索引。
  十二、 ORDER BY 后面的条件必须是同一索引的属性,排序顺序必须一致(比如都是升序或都是降序)。
  十三、 所有GROUP BY列引用同一索引的属性,并且索引必须是按顺序保存其关键字的。
  十四、 JOIN 索引,所有匹配ON和where的字段应建立合适的索引。
  十五、 对智能的扫描全表使用FORCE INDEX告知MySQL,使用索引效率更高。
  十六、 定期ANALYZE TABLE tbl_name为扫描的表更新关键字分布 。
  十七、 定期使用慢日志检查语句,执行explain,分析可能改进的索引。
  十八、 条件允许的话,设置较大的key_buffer_size和query_cache_size的值(全局参数),和sort_buffer_size的值(session变量,建议不要超过4M)。
  首先分析项目的数据表,都会有什么样的操作,比如产品列表,会按照分类、品牌等做where,按照时间、价格等排序(order by),所以做索引,个人觉得应该是按照业务逻辑去做。
  索引类型:
  (1)  普通索引
  最简单的索引方式,没有太多的约束,创建方式如下:
  创建:create index indexname on tablename(column(length));如果是字符型的字段,要指定length
  (建表时指定)create table tablename ([….],index [indexname] (column(length));
  修改:alter tablename add index [indexname] on (column(length))
  删除:drop index indexname on tablename
  (2)  唯一索引
  和普通索引的区别就是列值要唯一,允许有空值。(组合索引那组合后的列值也必须唯一)
  创建:create unique index indexname on tablename (column(length))
  (健表时指定)create table ([….],unique [indexname] (column(length)))
  修改:alter tablename add unique [indexname] on (column(length))
  (3)  主键索引
  主键索引就比较清晰了,大家经常用到,只需要记住两个概念就行了,不能为空,列值唯一。
  当然了,还有就是一个表只能有一个主键。
  (4)  全文索引
  Mysql3.23开始支持全文索引,在项目中还真没用过,都用了sphinx全文检索了。所以在此不赘述了。
  
  单列索引和组合索引
  为了描述这两个概念,我们首先建一张测试表
  Create table student(
  Id int not null auto_increment primary key,
  Name char(100) not null,
  Age tinyint not null,
  Score tinyint not null default 0
  )engine=myisam default
  测试表名为student,字段name是名字,age是年龄,score是成绩。

  现在有这么一条查询语句:select>  首先分析单列索引:
  如果在name、age和score的每个字段上建立索引,那就会产生三个结果集,然后再取其交集,最后在得出查询结果
  组合索引:
  Alter table student add index name_age_score on (name(10),age,score);
  建立组合索引,其中name(10),只提取名称的前部分,既能减少索引文件的体积,又能加快插入操作。
  有了组合索引,就相当于有了如下三个索引:
  (name,age,socre)
  (name,age)
  (name)
  这也就是通常所说的“最左前缀”的概念,其实说简单点就是要按照索引的顺序进行排列
  如果有了这个组合索引,那上面那条查询语句一次即可命中
  什么时候用索引
  首先mysql只对,between,in,like使用索引,因此where和join(on)的时候就应该考虑到使用什么样的索引,而且要记住一条sql语句只能使用一个索引,比如有where和order by同时出现的时候,order by 即使用的是索引字段,他也不会走索引。
  索引的弱点
  (1)   加了索引之后,那insert、delete和update操作都要更新索引,会造成一些附加操作
  (2)   索引是保存在物理文件(.MYI)里的,所以如果在一张大表上创建索引,势必会造成索引文件也比较大
2、MySQL优化之索引创建规则

  •   表的主键、外键必须有索引;
  •   数据量超过300的表应该有索引;
  •   经常与其他表进行连接的表,在连接字段上应该建立索引;
  •   经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
  •   索引应该建在选择性高的字段上;
  •   索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
  •   复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:

    •   正确选择复合索引中的主列字段,一般是选择性较好的字段;
    •   复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;
    •   如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
    •   如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
    •   如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;

  •   频繁进行数据操作的表,不要建立太多的索引;
  •   删除无用的索引,避免对执行计划造成负面影响;
  以上是一些普遍的建立索引时的判断依据。一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。因为太多的索引 与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合 索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-607239-1-1.html 上篇帖子: Docker安装Mysql数据库容器 下篇帖子: MySQL的复制(主从,主主,基于ssl)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表