Mysql数据优化及建表思路

Mysql千万级大表的优化过程

方案概述

方案一:优化现有Mysql数据库。优点:不影响限有业务,源程序不需要修改代码,成本最低。缺点:有优化瓶颈,数据量过亿就玩完了。

方案二:升级数据库类型,换一种100%兼容Mysql的数据库。
优点:不影响现有业务,源程序不需要修改代码,你几乎不需要做任何操作就能升级数据库性能,缺点:多花钱。

方案三:一步到位,大数据解决方案,更换newSQL/noSQL数据库。优点:没有数据容量瓶颈,缺点:需要修改源程序代码,影响业务,总成本最高。、

优化现有MySQL数据库

数据库设计

表字段避免null值出现,null值很难查询优化且占用额外的索引空间,推荐默认数组0替代null。
尽量使用int而非BIGINT,如果非负则加上UNSIGNED(这样数值容量扩大一倍),当然能使用TINYINT、SMALLINT、MEDIUM_INT更好。
使用枚举或者整数代替字符串类型
尽量使用TIMESTAMP而非DATETIME。
单表不要有太多字段,建议在20以内。
用整形来存IP

索引设计:

1.索引并不是越多越好,要根据查询有针对性的创建,考虑在where和order by命令上涉及的列建立索引,可根据explain来查看是否使用了索引还是全表扫描。
2.应尽量避免在WHERE子句中对字段进行NULL值判断,否则将导致引擎放弃使用索引而进行全表扫描。
3.值分布很稀少的字段不适合索引,例如“性别”这种只有两三个值的字段。
4.不用外键,由程序保证约束。
5.尽量不用UNIQUE,由程序保证约束。
6.使用可存下数据的最小的数据类型,整形<date,time <char,varchar<blob*
7.尽可能使用not null定义字段。
8.尽量少用text,非用不可最好分表。
9.where条件中<,<=,=,>,>=,between,in,以及like字符串+通配符(%)出现的列。

SQL编写

1.使用limit对查询结果的记录进行限定
2.避免select *,将需要查找的字段列出来。
3.使用连接(join)来代替子查询
4.不做列运算:select id where age+1=10,任何对列的操作都将导致表扫描,它包括数据库函数。
5.SQL语句尽可能简单:一条SQL只能在一个CPU运算;大语句拆小语句,减少锁时间;一条大SQL可以堵死整个库。
6.避免%xxx式查询
7.少用join
8.尽量避免在WHERE子句中使用!=或者<>操作符,否则将引擎放弃使用索引而进行全表扫描。
9.列表数据不要拿全表,要使用limit来分页,每页数量也不要太大。

分库:

把一个数据库分成多个,建议做个读写分离就行了,真正的做分库会带来大量的开发成本,得不偿失!不推荐使用。

分表


分表就是把一张大表,按照如上过程都优化了,还是查询卡死,那就把这个表分成多张表,把一次查询分成多次查询,然后把结果组合返回给用户。

分表分为垂直拆分和水平拆分,通常以某个字段做拆分项。比如以id字段拆分为100张表:表名为 tableName_id%100。

但:分表需要修改源程序代码,会给开发带来大量工作,极大的增加了开发成本,故:只适合在开发初期就考虑到了大量数据存在,做好了分表处理,不适合应用上线了再做修改,成本太高!!!而且选择这个方案,都不如选择我提供的第二第三个方案的成本低!故不建议采用。

升级数据库

开源数据库会带来大量的运维成本且其工业品质和MySQL尚有差距,有很多坑要踩,如果你公司要求必须自建数据库,那么选择该类型产品。如tiDB pingcap/tidb,Cubrid Open Source Database With Enterprise Features。

阿里云POLARDB,POLARDB 是阿里云自研的下一代关系型分布式云原生数据库,100%兼容MySQL,存储容量最高可达 100T,性能最高提升至 MySQL 的 6 倍。POLARDB 既融合了商业数据库稳定、可靠、高性能的特征,又具有开源数据库简单、可扩展、持续迭代的优势,而成本只需商用数据库的 1/10。

阿里云OcenanBase,淘宝使用的,扛得住双十一,性能卓著,但是在公测中,我无法尝试,但值得期待。

阿里云HybridDB for MySQL (原PetaData),云数据库HybridDB for MySQL (原名PetaData)是同时支持海量数据在线事务(OLTP)和在线分析(OLAP)的HTAP(Hybrid Transaction/Analytical Processing)关系型数据库。

腾讯云DCDB,DCDB又名TDSQL,一种兼容MySQL协议和语法,支持自动水平拆分的高性能分布式数据库——即业务显示为完整的逻辑表,数据却均匀的拆分到多个分片中;每个分片默认采用主备架构,提供灾备、恢复、监控、不停机扩容等全套解决方案,适用于TB或PB级的海量数据场景。

换大数据引擎

hadoop家族。hbase/hive怼上就是了。但是有很高的运维成本,一般公司是玩不起的,没十万投入是不会有很好的产出的!

阿里云的MaxCompute配合DataWorks,使用超级舒服,按量付费,成本极低。

MaxCompute可以理解为开源的Hive,提供SQL/mapreduce/ai算法/python脚本/shell脚本等方式操作数据,数据以表格的形式展现,以分布式方式存储,采用定时任务和批处理的方式处理数据。DataWorks提供了一种工作流的方式管理你的数据处理任务和调度监控。

当然你也可以选择阿里云hbase等其他产品,基本都是图形界面操作,大概写了300行SQL,费用不超过100块钱就解决了数据处理问题。

SQl语句技巧

技巧1 比较运算符能用“=”就不用“<>”
“=”增加了索引的使用几率

技巧2明知只有一条查询结果,那请使用“limit 1”
“limit 1”可以避免全表扫描,找到对应结果就不会再继续扫描了。

技巧3 为列选择合适的数据类型
能用TINTINT就不用SMALLINT,能用SMALLINT就不用INT,磁盘和内存消耗越小越好。

技巧4.将大的DELETE,UPDATE OR INSET 查询变成多个小查询
能写一个几十行、几百行的SQL语句不会显得逼格很高,为了达到更好的性能以及更好的数据控制,你可以将它们变成多个查询。

技巧5,为获得相同结果集的多次执行,请保持SQL语句前后一致
这样做的目的是为了充分利用查询缓冲
比如根据地域和产品id查询产品价格,第一次使用了:

Select price from order where id=123456 and region=’beijing’;

那么第二次同样的查询,请保持以上语句的一致性,比如不要将where语句里面的id和region位置调换顺序。

技巧6:尽量避免使用“select *”
如果不查询表中的所有的列,尽量避免使用select *,因为它会进行全表扫描,不能有效利用索引,增加了数据库服务器的负担,以及它与应用程序客户端之间的IO开销。
技巧7:where、join、order by子句里面的列尽量被索引
只是“尽量”,因为索引太多也会降低性能

技巧8:使用limit实现分页逻辑
不仅提高性能,同时减少了不必要的数据库和应用的网络传输。

数据库中2表之间的关系,怎么设计更加优雅?

在这里插入图片描述

在这里插入图片描述
方式一:如上数据库中2表,通过sid这个字段去管理学生表和成绩表,这是比较常见的思路。

方式二:创建一张关系表,叫学生成绩关系表,表里关键字段就是SID(学生主键)、CID(成绩的主键)。

优缺点对比:
1.数据量,当2张业务表数据不大的情况下,优先考虑方式1,数据量大就选择方式2

2.1对1,1对多,多对多,业务情况比较复杂情况,优化选择方式2,比较固定的关系可以选择方式1.

纵表思路

业务场景:一张表有40多个属性,并且顺业务迅猛发展,字段还在不断增加。
具体设计思路:
1.一张主表、一张主表的扩展属性表

2.学生表为主表,它的扩展表,下面多了3个属性身高、体重、爱好

3.如果明天PD突然要你加个喜欢吃的食物、星座什么的属性,你不需要改表结构了,扩展非常方便。
在这里插入图片描述
3.对应Java代码优雅设计思路,这个attr_key的值可以设计成枚举值大字段

4.业务场景:如配置表,业务发展太快,可以把具体规则以json格式放大字段。

为了扩展方便,经常在表中添加ext_info字段,里面存放的是json内容。

纵表缺点 

优点:大家都看到了比较明显,可以动态添加业务属性,不用改表结构


缺点:如果PD突然要你按爱好(扩展表属性的字段去查询)页面查询需求,你就要哭了,这里代码就复杂化了,你不能一次性查询出来。需要2个步骤。

总结


数据库2张表关系的建议,需要考虑业务复杂度、数据量,采用创建关系表,还是在原来表上增加字段

纵表的优缺点很明显,请根据业务来考虑设计吧

大字段扩展字段很方便,需要配合json来存取。

动态扩展、性能、业务强关系、业务弱关系,需要自己根据经验去平衡。

猜你喜欢

转载自blog.csdn.net/weixin_46011971/article/details/108816704