MySQL使用总结

建表

create table test(
        id int(11) NOT NULL AUTO_INCREMENT,
        a int(4) NOT NULL DEFAULT 0,
        b char(10) NOT NULL DEFAULT ‘’,
        c varchar(255) NOT NULL DEFAULT ‘’,
        create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
         update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        PRIMARY KEY (id),
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

show create table test; 查看创建表DDL
    show engine; 查看mysql引擎

1.库名表名一律小写,见名知意,linux风格命令,比如a_b_c

2.引擎用InnoDB,高并发高可用互联网业务都是InnoDB,云服务商提供的云DB也仅仅支持InnoDB,MyISAM已被弃用

3.字符集用UTF-8,汉子3个字节,英文1个字节,通用无乱码风险,存储表情等特殊符号时需用utf8mb4,占4个字节

4.所有字段NOT NULL且必须有默认值,NULL用特殊字符保存,需要更多的存储空间(5.5后优化了),查询时只能使用is[not] null,不能使用=/!=/in/not in,索引不存储NULL记录,导致NULL列索引统计更复杂,也更难优化

5.列类型使用顺序int > timestamp/year/date/time/datetime > enum/char > varchar > text/blob, int类型效率高,char涉及字符集,int指定长度类型,不要使用int(11)默认长度

6.ip用int存储,占4字节,电话号码可能出现+/-/()等字符,用varchar(20),可用like模糊查询

7.小数字段推荐使用 decimal 类型,float 和 double 精度不够,特别是涉及金钱的业务,必须使用 decimal

8.尽量避免据库中使用 text/blob 来存储大段文本、二进制数据、图片、文件等内容,而是将这些数据保存成本地磁盘文件或对象存储系统中,数据库中只保存其路径等索引信息

9.表都要有主键,推荐使用unsigned int,以便从库高效删除数据,主键也不该被修改,字符串不能做主键,如果不指定主键,innodb会使用唯一且非空值索引代替

10.存在自增列的表,自增列上必须存在一个单独的索引,若在复合索引中,自增列必须置于第一位

11.表不要有外键约束,提高插入并发效率,外键在大并发下容易产生死锁,应在业务代码中保证一致性

12.平衡范式与冗余,为提高效率可以牺牲范式设计,冗余数据; 大字段,访问频度低的字段拆分到单独的表中存储,分离冷热数据

13.避免使用触发器/视图/触发器/用户自定义函数,调试迁移拍错困难,扩展性差,数据库存储数据为主,降低业务逻辑和数据存储的耦合度,应由应用层业务程序取而代之

14.单表列不超过20,记录控制在千万级别,拒绝3B(big),大sql,大事务,大批量

15.短期内业务达不到一个比较大的量级,建议不要使用分区表,分区表主要用作归档管理,多用于快递行业和电商行业订单表,莫迷信分区表提升性能,除非业务中 80% 以上的查询走分区字段

查询

1.不能select *,只获取必要字段,能有效利用索引覆盖,表结构变更时也对业务程序无影响,同理insert时也必须指定字段

2.禁止在where条件列使用函数或者表达式,以免索引失效,全表扫描

3.禁止负向查询以及%开头的模糊查询,导致不能命中索引,全表扫描

4.or改写成in或union,最新mysql已优化,in范围须少于50个

5.union all代理union,union有去重开销

6.少用join,大表禁止join,join列上要有索引,两张表join必须让小表做驱动表,务必使用同类型比较,避免全表扫描

7.LIMIT 分页优化,LIMIT 80000,10这种操作是取出80010条记录,再返回后10条,数据库压力很大,推荐先确认首记录的位置再分页,如SELECT * FROM test WHERE id >80000 LIMIT 10

8.应用程序捕获SQL异常,方便调试

9.explain;show slow log;查看执行计划和慢查询

10.insert … on duplicate key update 不存在更新,存在update

索引

1.合理使用索引,改善查询,但减慢更新,更新频率高的列不能建索引

2.唯一索引命名uniq_列名, 非唯一索引idx_列名

3.单表索引控制在5个以内,太多起不到过滤作用了,索引也占空间,索引多可能影响更新性能,索引列少更新,不在索引列做计算

4.varchar字段上建索引时,建议指定索引长度,不要直接将整个列建索引,一般 varchar 列比较长,指定一定长度作索引已经区分度够高,没必要整列建索引,整列建索引会显得比较重,增大了索引维护的代价,可以用 count(distinct left(列名, 索引长度))/count(*)来看索引区分度

5.选择业务中SQL过滤走的最多的并且cardinality值比较高的列建索引,业务SQL不走的列建索引是无意义的,字段的唯一性越高即代表 cardinality值越高,索引过滤效果也越好,一般索引列的 cardinality 记录数小于10%是一个低效索引,例如性别字段;

6.组合索引最左前缀原则,避免重复建索引,如果建立了(a,b,c),相当于建立了(a), (a,b), (a,b,c),但不是值SQL语句的where顺序要和组合索引一致

7.InnoDB是BTree索引,一个表只能有一个聚簇索引,即索引和数据记录存储在一起(记录只有一份),一般主键上是聚簇索引,非主键上是普通索引,叶子节点存储索引和主键(不是记录指针),Hash索引一般用在内存数据库中

8.普通索引叶子节点存储主键,因此较长的列不能做主键,普通索引上查询先通过索引找到主键,然后在聚簇索引上通过主键找记录

9.建议使用趋势递增的key做主键,由于数据行与索引一体,这样不至于插入记录时,有大量索引分裂,行记录移动

10.B+Tree高度低,查询效率高,非叶子节点不存储key,叶子节点存储key和记录,根到所有叶子节点路径长度相同,叶子节点可存储多个记录,可利用局部性原理进行磁盘预读提高磁盘IO,叶子节点增加双向连接变成双向有序链表,便于范围查询/有序查询,非叶子节点一般被缓存,叶子节点包含record从磁盘读取

索引失效

- 隐式类型转换,如索引a的类型是varchar,SQL 语句写成 where a = 1 varchar 变成了int
- 对索引列进行数学计算和函数等操作,例如:使用函数对日期列进行格式化处理
- join 列字符集不统一
- 多列排序顺序不一致问题,如索引是 (a,b),SQL 语句是 order by a b desc
- 模糊查询使用的时候对于字符型xxx%形式可以走到一些索引,其他情况都走不到索引;
- 使用了负方向查询(not,!=,not in 等)

锁&事物

1.业务代码中事务及时提交,避免产生没必要的锁等待

2.InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上,如果访问没有命中索引,无法使用行锁,将要退化为表锁,锁粒度较大,会影响并发

3.记录锁(Record Locks)锁定索引记录,阻止其他事物对该记录的修改;间隙锁(Gap Locks)锁定一个范围,防止范围内数据被其他事物更改;临建锁(Next-Key Locks)锁定索引记录及其之前紧邻的索引区间,防止幻读

4.并发控制用于保证数据的一致性,通常的方法有锁Locking和数据多版本Multi Vesion;共享锁(Share Locks,记为S锁)读取数据时加S锁,读读可并行,排他锁(eXclusive Locks,记为X锁),修改数据时加X锁,写读,写写不可以并行;数据Multi Version即CopyOnWrite,写时更新新版本,读时读取旧版本,实现读写并行

5.事物ACID,A(atomic)原子性要么不执行,要么全执行;C(consistence)事物前后数据处于一致状态;I(independent)事物之间不会有影响;D(durable)事物执行完成后对数据的改变不会因其他外部因素变化

6.redo日志用于保障已提交事物的ACID,redo log是磁盘顺序写,速度快,在定期将内存记录数据写磁盘

7.undo日志用于保障未提交事物ACID,undo log记录未提交事物时数据的旧版本,用于事物的回滚,事物提交后undo日志则可删除,存放undo log的地方叫回滚段

8.多版本并发控制MVCC(Multi Version Concurrency Control)就是通过“读取旧版本数据”也就是回滚段中数据来降低并发事务的锁冲突,提高任务的并发度

9.回滚段数据是历史数据快照,在写事物未提交前可进行无锁快照读(Snapshot Read),这种一致性不加锁的读(Consistent Nonlocking Read),就是InnoDB并发如此之高的核心原因之一,这里的一致性是指事务读取到的数据,要么是事务开始前就已经存在的数据(当然,是其他已提交事务产生的),要么是事务自身插入或者修改的数据

10.普通select都是快照读,除非显示加锁(select xxx for update/lock in share mode)

11.事物隔离性指多个并发事物之间互不影响,通过不同策略的锁实现的隔离级别不同;读未提交(Read Uncommitted)select不加锁,并发度高,隔离级别低;可重复读(Repeated Read, RR)是InnoDB默认隔离级别,普通select快照读不加锁,加锁select是行锁或表锁;读提交(Read Committed, RC)是互联网最常用的隔离级别,普通select也是快照读;串行化(Serializable)所有select语句都会被隐式的转化为select xxx  in share mode,如果有未提交的事务正在修改某些行,所有读取这些行的select都会被阻塞住,这是一致性最好的,但并发性最差的隔离级别

12.RR下事物里读取数据是第一次Read View,RC下每次读都会建立Read View

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值