美文网首页
数据库相关

数据库相关

作者: 玩裤 | 来源:发表于2016-09-04 23:49 被阅读0次

    参考链接:
    http://www.nowamagic.net/academy/detail/32061020
    http://www.cnblogs.com/hi-bazinga/archive/2012/06/05/2536806.html
    http://www.cnblogs.com/ybwang/archive/2010/06/04/1751279.html
    http://www.cnblogs.com/phoenixbai/p/mysql_best_practices.html
    http://ariyue.iteye.com/blog/553541

    基本知识

    <p>
    ** 四大范式**
    第一范式:每个属性不可再分,属性原子性(高效查询提高性能)
    第二范式:非主属性完全依赖于主属性,即消除非主属性对主属性的部分函数依赖关系(完全但不是直接,少冗余)
    第三范式:确保每列都和主键列直接相关,而不是间接相关。非主属性对主属性不存在传递函数依赖关系(完全且直接)
    BCNF:非主键字段必须依赖于整个主键字

    事务隔离级别
    读未提交:实际很少用。
    读已提交:大多数数据库的默认级别。解决脏读问题。
    可重读:mysql默认。解决了脏读和不可重复读问题。但有幻读问题。
    可串行化:最高的级别,强制事务排序使之不会相互冲突,解决幻读问题。但会有性能问题。

    脏读(rollback):A已更新一份数据,B在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。
    不可重复读(update):事务两次查询之中数据的内容不一致 ,别的事务更新所致。
    幻读(insert):事务两次查询之中数据的条数不一致 ,别的事务新增所致。
    =====================
    四个方面:数据库设计、SQL语句优化、数据库参数配置、恰当的硬件资源和操作系统。

    一、数据库设计
    1. 适度的反范式,根据业务场景做适度的冗余可以大大提高性能。
    2. 适当建立索引,以及复合索引。Cardinality越大,Selectivity越高的字段,越是理想的建索引的对象
    3. 表的水平划分和垂直划分
    4. 主键不要设得太大 (InnoDB),因为它是以B+树形式存储数据文件的。
    5. 文件,图片等大文件用文件系统存储,数据库只存储路径。
    6. 避免频繁读写,尽量集中批量操作。
    7. 静态表会更快(固定长度的表,无VARCHAR, TEXT, BLOB可变长度的string类型的字段的表为静态表。否则,为动态表)。
    二、SQL语句优化

    慢日志

    参数文件里配置:
       slow_query_log=d:/slow.txt
       long_query_time = 2
    通过mysql自带的工具(mysqldumpslow.pl)来分析慢日志。

    2.Explain查看mysql执行计划

    QUERY最佳实践:

    1. 不要用 “SELECT *”,否则,会读多,传输多,且增加可避免的表扫描

    2. 不要 like ‘%item%’ but ‘item%’
      前面有%,这索引就没办法利用了。所以,若想用索引加快查询速度,那前面别加%.

    3. Cardinaltiy (基数) & Selectivity (选择比)
      Cardinality: 不同值的个数。如表t中其有100条记录, 字段owner也有100条值,但其中10个不相同的值。这10就是这字段的Cardinality.
      Selectivity: 10/100 = 10%就是这字段的selectivity.
      这概念主要用来判断此字段是否适合建索引。Cardinality越大,Selectivity越高的字段,越是理想的建索引的对象。有时数据库会根据这个值来决定,是利用索引还是扫表。所以说,不是你建了索引,人家就会用的。而且,索引不可太多,多了反而会拖慢更新速度。

    4. ORDER BY created DESC的优化
      时间排序是应用中比较常见的需求。细想,这时间不是自增长的嘛?那跟ID自增长不是一回事儿嘛? 所以说,在ORDER BY 时,用自增长的主键ID,会比用created,省一个FILE SORT操作。快很多的。

    5. Count(1), count(), count(owner)的区别
      count(1)等同于count(
      ),等同于count(任何一个NOT NULL的字段)
      count(owner):若owner是可NULL的,则数出来的数跟上面的三种情况会少的。少的正好是那些owner is null的个数。

    6. Don`t JOIN ON 不同数据类型
      A表user_id作为B表的外键,这种很常见。此时,需注意user_id字段的类型,在两张表里都要保持一致。这样节省不必要的开支,比如,数据库替你做类型转换等。

    7. 不要用全文索引(full-text index)
      当前只有MyISAM才支持全文索引。而且,不太好用,可自定义性比较差,所以完全无视它即可。若真需要做全文索引,还是考虑用Lucene, Solr, ElasticSearch, Sphinx, Groonga, Xapian等吧。个个都是行家里手,功能齐全,可定义性强,随你搞。

    8. Limit n,m 慢,慎用
      大部分人翻页,可能都是靠这个的。数据量大时,这显然会很慢。网上有人推荐说,第一次查出来后,记住当前页的最后一个ID,然后,在查询下一页时,把这个ID做为限制条件加进去,然后取limit pagesize。
      诸如此类,若细想,应该是能想出点儿可行之策的我觉的。其实,当数据量很大时,你可以换个角度想,如继续在limit n,m上做文章能还是直接换个查询方式,如用搜索引擎等。

    百万级数据量时,limit优化

    小小的索引+一点点的改动就使mysql 可以支持百万甚至千万级的高效分页

    1. 建立复合索引
    2. 通用优化索引,找出id,再拼成 ”292,2492,38,12000“这样的字符串
    3. 再次用 where id in 语句查询出结果

    100万的数据,160万数据,15G表,190M索引
    如果对于有where 条件,又想走索引用limit的,必须设计一个索引,将where 放第一位,limit用到的主键放第2位,而且只能select 主键!

    三、数据库参数配置

    nnodb_additional_mem_pool_size = 64M
    innodb_buffer_pool_size = 5G

    四、合理的硬件资源和操作系统

    读写分离 binlog

    主库master用来写入,slave1—slave3都用来做select,每个数据库分担的压力小了很多。工具:mysql-proxy(官方),amobe for mysql(新浪)

    ====================
    导致引擎放弃使用索引而进行全表扫描常见情况:

    1. 在 where 子句中对字段进行 null 值判断
    2. 在 where 子句中使用!=或<>操作符
    3. 在 where 子句中使用 or 来连接条件,可以用 union all 来改写。
    4. in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据,对于连续的数值,能用 between 就不要用 in .
    5. 在 where 子句中对字段进行表达式操作
    6. 在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算
    7. 能用DISTINCT的就不用GROUP BY
    8. 尽量不要用SELECT INTO语句。 SELECT INOT 语句会导致表锁定,阻止其他用户访问该表。
    9. 避免在索引列上使用计算,not,in和<>等操作
    10. 当只需要一行数据的时候使用limit 1

    相关文章

      网友评论

          本文标题:数据库相关

          本文链接:https://www.haomeiwen.com/subject/olqrettx.html