首页 技术 正文
技术 2022年11月15日
0 收藏 391 点赞 2,345 浏览 2616 个字

个人认为以下军规主要为了适应海量数据场景,对于业务复杂性系统并一定完全按照此军规 一,核心军规

  • 不在数据库做计算,cpu计算务必移至业务层
  • 控制单表数据量,单表记录控制在千万级
  • 控制列数量,字段数控制在20以内
  • 平衡范式与冗余,为提高效率可以牺牲范式设计,冗余数据
  • 拒绝3B(big),大sql,大事务,大批量

 二,字段类军规

  • 用好数值类型

tinyint(1Byte)smallint(2Byte)mediumint(3Byte)int(4Byte)bigint(8Byte)bad case:int(1)/int(11)bigint从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字)。存储大小为 8 个字节。int从 -2^31 (-2,147,483,648) 到 2^31 – 1 (2,147,483,647) 的整型数据(所有数字)。存储大小为 4 个字节。int 的 SQL-92 同义字为 integer。smallint从 -2^15 (-32,768) 到 2^15 – 1 (32,767) 的整型数据。存储大小为 2 个字节。tinyint从 0 到 255 的整型数据。存储大小为 1 字节。 

  • 有些字符转化为数字

用int而不是char(15)存储ip

  • 优先使用enum或set

例如:`sex` enum (‘F’, ‘M’) ;ENUM保存的是TINYINT

  • 避免使用NULL字段

NULL字段很难查询优化NULL字段的索引需要额外空间NULL字段的复合索引无效bad case:`name` char(32) default null`age` int not nullgood case:`age` int not null default 0

  • 不在数据库里存图片

 三,索引类军规

  • 谨慎合理使用索引

改善查询、减慢更新索引一定不是越多越好(能不加就不加,要加的一定得加)覆盖记录条数过多不适合建索引,例如“性别” ;添加区分度高的索引能过滤掉80%的数据

  • 字符字段必须建前缀索引
  • 不在索引做列运算

-bad case:select id where age +1 = 10;-good case:$curDate = date(‘Y-m-d’); $res = mysql_query(‘select * from order where date < = $curDate’);

  • innodb主键合理使用自增列

主键建立聚簇索引主键不应该被修改字符串不应该做主键如果不指定主键,innodb会使用唯一且非空值索引代替

  • 不用外键,请由程序保证约束

 四,sql类军规

  • sql语句尽可能简单

一条sql只能在一个cpu运算大语句拆小语句,减少锁时间一条大sql可以堵死整个库

  • 简单的事务

事务时间尽可能短bad case:上传图片事务

  • 避免使用触发器,用户自定义函数,请由程序取而代之
  • 前导模糊查询不能使用索引

bad case:select * from order where desc like ‘%XX’good case:select * from order where desc like ‘XX%’

  • 避免使用not或!= 使用in替代,如果序列是连续的话使用between
  • 区分in和exists, not in和not exists

select * from 表A where id in (select id from 表B)上面sql语句相当于select * from 表A where exists(select * from 表B where 表B.id=表A.id)区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的sql语句?原sql语句select colname … from A表 where a.id not in (select b.id from B表)高效的sql语句select colname … from A表 Left join B表 on where a.id = b.id where b.id is null 

  • 如果明确知道只有一条结果返回,使用limit 1
  • 不用select *

消耗cpu,io,内存,带宽这种程序不具有扩展性

  • limit高效分页

limit越大,效率越低select id from t limit 10000, 10;应该改为 =>select id from t where id > 10000 limit 10; 

  • 使用union all替代union,union有去重开销
  • 尽量不用连接join
  • 务必请使用“同类型”进行比较,否则可能全表扫面

bad case :select * from user where phone=13800001234-使用varchar(20)存储手机号,解读:a)涉及到区号或者国家代号,可能出现+-()b)varchar可以支持模糊查询,例如:like“138%” 

  • 如果业务大部分是单条查询,使用Hash索引性能更好,例如用户中心

select * from user where uid=? select * from user where login_name=?原因:B-Tree索引的时间复杂度是O(log(n))Hash索引的时间复杂度是O(1) 

  • 打散批量更新
  • 使用性能分析工具

show profile;mysqlsla;mysqldumpslow;show slow log;show processlist;show query_response_time(percona)explain; EXPLAIN 查看SQL执行计划。下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 转载&修改:赶集mysql军规转载&修改:赶集mysql军规 转载&修改:赶集mysql军规

转载&修改:赶集mysql军规

转载&修改:赶集mysql军规

    1. type列,连接类型。一个好的sql语句至少要达到range级别。杜绝出现all级别
    2. key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式
    3. key_len列,索引长度
    4. rows列,扫描行数。该值是个预估值
    5. extra列,详细说明。注意常见的不太友好的值有:Using filesort, Using temporary

 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,028
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,518
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,367
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,146
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,858