zoukankan      html  css  js  c++  java
  • 01-sql优化及索引

    掌握必要的sql优化知识对于程序员来说是必须的,因为各种程序本质来说就是对数据的处理,无非就是简单的增删改查和复杂的增删改查而已,所以对于数据的分析处理是非常重要的
    首先推荐一本书<深入浅出MYSQL>,由网易DBA团队编写,写的非常好,感兴趣的朋友可以买来看看
    下面介绍sql优化:
    1.主键查询
    查询尽量使用主键查询,因为有主键索引
    其它索引后面介绍
    2.合理使用字段,及字段长度
    原则就是能保证存储要求,也需预留空间
    如果字段长度过长,会增加不必要的空间
    例如邮政编码字段,显然VARCHAR(6)就行了,不需要VARCHAR(255)
    3.尽量使用join关联查询替代子查询
    子查询就是将一个查询的结果作为另一个查询的条件或者要查询的表再次查询
    这样查询本质上属于两次查询了,mysql会创建临时表来存储第一次查询结果,这样会消耗空间
    每次查询都是要消耗资源的,所以这种效率不是很好
    数据量小看不出来,数据量大的话使用关联查询速度更快,可以去试验
    如果子查询非要用的话,最好只出现一次,出现两次或以上严重影响效率,因为计算机会对sql语句生成执行计划,再去执行,如果子查询过多,人都看晕了,同样计算机识别语句的意思,然后生成执行计划也会慢很多
    4.网上看到有说使用外键的,工作中从来没用过外键,这种说法不行,现在都是快速开发
    外键的作用被业务层取代了,直接写在代码中
    用外键不易修改/删除数据,很麻烦,实际开发中也很少/几乎没有公司使用外键
    所以该方法不可取
    5.少写或不写select * ,要什么字段就取什么字段
    6.查询缓存的使用
    mysql默认是开启查询缓存了
    就是说相同的查询,第二次会直接访问缓存结果
    但是有些sql中的函数如now(),这种是时时变化的,写在sql语句中不会开启查询缓存
    所以在sql中可不使用这些函数就不使用,用变量传入sql中,这样就开启缓存了
    7.当只要一行数据时使用limit 1,mysql数据库引擎会在找到一条数据后停止搜索,而不是继续往后查找下一条符合的数据,如果需的数据不是很多,但是返回量很大的时候也要使用limit限制返回量
    8.使用EXPLAIN + 查询语句可以知道sql语句执行的信息
    可以看出查询扫描类型,这个后面介绍
    也可以直接在客户端navicat查看概况,里面会显示查询时间主要消耗在哪里...
    9.在比如数据量小且固定的情况下,如性别,省市区等等,可以使用ENUM字段(枚举),ENUM 类型是非常快的,它实际上保存的是TINYINT,但其外表上显示为字符串..
    10.复杂sql语句的拆分与避免锁表
    在访问量很高的项目中/特别是互联网项目中尽量避免写复杂的sql语句,因为复杂的sql语句执行时间相对而言要长,会造成锁表,就是说当前sql执行的这段时间,别的sql不能操作该表,在访问量很高的网站上,这时就会有大量的sql操作请求积累在数据库中,这样很可能数据库就崩了
    11.建立索引(重点)
    这个是最重要的,因为不用索引和用索引的查询速度相差了几十倍
    如果不用索引,mysql会从第一条数据开始读取,读完整张表然后获取需要的数据
    用了索引,mysql会按照索引快速的到一个位置去手搜索数据
    就把索引比作字典前面那些拼音笔画索引,显然用这个查比你拿着字典从第一页一页页的翻要快的多
    但是如果你获取的是大部分数据,这时就是顺序读取要快了
    索引分类:
    主键索引
    唯一索引
    普通索引
    最合适索引字段是常用于在where语句后的字段,也就是查询条件
    字段中值基数越大,越不同,索引效果越好,如果数据量小且值又很多相同的,效果就不明显,就不需要用索引了
    不要过度索引,因为额外的索引都是要占用磁盘空间的,修改表数据时,索引必然是要更新的,这样也是要浪费时间的,还有sql生成执行计划的时候也会考虑各个索引,这样看来多余的索引反而不好,不利于查询优化
    12.EXPLAIN + 查询语句分析
    可以看到type:访问类型,key:实际使用的索引,rows:扫描的行数
    可以检查设置的索引有没有用到,扫描行数越少显然速度越快了
    访问类型就是mysql是怎么找到所需的数据的
    type分类:
    all:
    全表扫描,就是mysql从第一条数据开始,一条条查询
    index:
    索引全扫描,就是遍历整个索引查找
    如:select title from film
    title上有索引,但是根据的是所有的索引去查询的数据,这没能很好体现索引的效果
    range:
    索引范围扫描,常用于<,<=,>,between等操作符,就是设定索引值的范围
    如:select * from payment where customer_id <= 350
    ref:
    使用非唯一性索引匹配单个值然后返回
    非唯一索引相对唯一索引而言的,唯一索引包括主键和设置其它唯一索引
    如:select * from payment where customer_id = 350
    eq_ref:
    类似ref,但是使用的是唯一索引,对于每个索引键值,表中只一条记录匹配,简单的说就是多表连接中使用主键或者唯一性索引字段作为关联条件
    const/system:
    最多匹配到一条数据
    就是根据主键或者唯一性索引字段来查询单表,速度最快

  • 相关阅读:
    ORACLE字符集基础知识
    Outlook 2013 在邮件里面点击超链接时弹出“组织策略阻止我们为您完成此操作”
    Apache Kafka: 优化部署的10个最佳实践
    经济学人使用Golang构建微服务历程回顾
    如何做自己的服务监控?spring boot 2.x服务监控揭秘
    web框架的前生今世--从servlet到spring mvc到spring boot
    如何做自己的服务监控?spring boot 1.x服务监控揭秘
    手机上不了网
    Cross-Browser, Event-based, Element Resize Detection(转)
    迷你MVVM框架 avalonjs 组件编写指南
  • 原文地址:https://www.cnblogs.com/jaro/p/8862165.html
Copyright © 2011-2022 走看看