mysql数据库开发常见问题及优化

mysql 数据库是被普遍应用的关系型数据库,其体积小、支持多处理器、开源并免费的特性使其在 Internet 中小型网站中的使用率尤为高。在使用 mysql 的过程当中不规范的 SQL 编写、非最优的策略选择均可能致使系统性能甚至功能上的缺陷。
    mysql

恰巧就在前几天,本人所在公司的云事业部举办了一场关于 mysql 的技术交流会,其中一个 part 正是聚焦于开发过程当中 mysql 数据库设计及使用的常见问题,并提出相关优化方案。根据会议内容并查阅相关资料,本人对这个 part 进行了一次小结,结合本身的工做经历及理解造成此文以供分享,但愿能有助于各位同行解决工做中的相关问题。sql

本文将就如下三个问题进行展开:数据库

    1. 库表设计
    2. 慢 SQL 问题
    3. 误操做、程序 bug 时怎么办

 

1、库表设计

1.1 引擎选择

在 mysql 5.1 中,引入了新的插件式存储引擎体系结构,容许将存储引擎加载到正在运新的 mysql 服务器中。使用 mysql 插件式存储引擎体系结构,容许数据库专业人员或者设计库表的软件开发人员为特定的应用需求选择专门的存储引擎,彻底不须要管理任何特殊的应用编码要求,也无需考虑全部的底层实施细节。所以,尽管不一样的存储引擎具备不一样的能力,应用程序是与之分离的。此外,使用者能够在服务器、数据库和表格三个层级中存储引擎,提供了极大的灵活性。服务器

mysql 经常使用的存储引擎包括 MYISAM、Innodb 和 Memory,其中各自的特色以下:并发

    1. MYISAM : 全表锁,拥有较高的执行速度,一个写请求请阻塞另外相同表格的全部读写请求,并发性能差,占用空间相对较小,mysql 5.5 及如下仅 MYISAM 支持全文索引,不支持事务。
    2. Innodb:行级锁(SQL 都走索引查询),并发能力相对强,占用空间是 MYISAM 的 2.5 倍,不支持全文索引(5.6 开始支持),支持事务。
    3. Memory : 全表锁,存储在内存当中,速度快,但会占用和数据量成正比的内存空间且数据在 mysql 重启时会丢失。

基于以上特性,建议绝大部份都设置为 innodb 引擎,特殊的业务再考虑选用 MYISAM 或 Memory ,如全文索引支持或极高的执行效率等。数据库设计

1.2 分表方法

在数据库表使用过程当中,为了减少数据库服务器的负担、缩短查询时间,经常会考虑作分表设计。分表分两种,一种是纵向分表(将原本能够在同一个表的内容,人为划分存储在为多个不一样结构的表)和横向分表(把大的表结构,横向切割为一样结构的不一样表)。函数

其中,纵向分表常见的方式有根据活跃度分表、根据重要性分表等。其主要解决问题以下:工具

    1. 表与表之间资源争用问题;
    2. 锁争用机率小;
    3. 实现核心与非核心的分级存储,如UDB登录库拆分红一级二级三级库;
    4. 解决了数据库同步压力问题。

横向分表是指根据某些特定的规则来划分大数据量表,如根据时间分表。其主要解决问题以下:性能

    1. 单表过大形成的性能问题;
    2. 单表过大形成的单服务器空间问题。

1.3 索引问题

索引是对数据库表中一个或多个列的值进行排序的结构,创建索引有助于更快地获取信息。 mysql 有四种不一样的索引类型:测试

    1. 主键索此 ( PRIMARY )
    2. 惟一索引 ( UNIQUE )
    3. 普通索引 ( INDEX )
    4. 全文索引(FULLTEXT , MYISAM 及 mysql 5.6 以上的 Innodb )

创建索引的目的是加快对表中记录的查找或排序,索引也并不是越多越好,由于建立索引是要付出代价的:一是增长了数据库的存储空间,二是在插入和修改数据时要花费较多的时间维护索引。

在设计表或索引时,常出现如下几个问题:

    1. 少建索引或不建索引。这个问题最突出,建议建表时 DBA 能够一块儿协助把关。
    2. 索引滥用。滥用索引将致使写请求变慢,拖慢总体数据库的响应速度(5.5 如下的 mysql 只能用到一个索引)。
    3. 从不考虑联合索引。实际上联合索引的效率每每要比单列索引的效率更高。
    4. 非最优列选择。低选择性的字段不适合建单列索引,如 status 类型的字段。

 

2、慢 SQL 问题

2.1 致使慢 SQL 的缘由

在遇到慢 SQL 状况时,不能简单的把缘由归结为 SQL 编写问题(虽然这是最多见的因素),实际上致使慢 SQL 有不少因素,甚至包括硬件和 mysql 自己的 bug。根据出现的几率从大到小,罗列以下:

    1. SQL编写问题
    2. 业务实例相互干绕对 IO/CPU 资源争用
    3. 服务器硬件
    4. MYSQL BUG

2.2 由 SQL 编写致使的慢 SQL 优化

针对SQL编写致使的慢 SQL,优化起来仍是相对比较方便的。正如上一节提到的正确的使用索引能加快查询速度,那么咱们在编写 SQL 时就须要注意与索引相关的规则:

    1. 字段类型转换致使不用索引,如字符串类型的不用引号,数字类型的用引号等,这有可能会用不到索引致使全表扫描;
    2. mysql 不支持函数转换,因此字段前面不能加函数,不然这将用不到索引;
    3. 不要在字段前面加减运算;
    4. 字符串比较长的能够考虑索引一部份减小索引文件大小,提升写入效率;
    5. like % 在前面用不到索引;
    6. 根据联合索引的第二个及之后的字段单独查询用不到索引;
    7. 不要使用 select *;
    8. 排序请尽可能使用升序 ;
    9. or 的查询尽可能用 union 代替 (Innodb);
    10. 复合索引高选择性的字段排在前面;
    11. order by / group by 字段包括在索引当中减小排序,效率会更高。

除了上述索引使用规则外,SQL 编写时还须要特别注意一下几点:

    1. 尽可能规避大事务的 SQL,大事务的 SQL 会影响数据库的并发性能及主从同步;
    2. 分页语句 limit 的问题;
    3. 删除表全部记录请用 truncate,不要用 delete;
    4. 不让 mysql 干多余的事情,如计算;
    5. 输写 SQL 带字段,以防止后面表变动带来的问题,性能也是比较优的 ( 涉及到数据字典解析,请自行查询资料);
    6. 在 Innodb上用 select count(*),由于 Innodb 会存储统计信息;
    7. 慎用 Oder by rand()。

 

3、分析诊断工具

在平常开发工做中,咱们能够作一些工做达到预防慢 SQL 问题,好比在上线前预先用诊断工具对 SQL 进行分析。经常使用的工具备:

    1. mysqldumpslow
    2. mysql profile
    3. mysql explain

具体使用及分析方法在此就不赘述,网上有丰富的资源能够参考。

 

4、误操做、程序 bug 时怎么办

提出这个问题显然主要是针对刚开始工做的年轻同行们……实际上误操做和程序 bug 致使数据误删或者混乱的问题并不是少见,可是刚入行的开发工做者会比较紧张。一个成熟的企业每每会有完善的数据管理规范和较丰富的数据恢复方案(初创公司除外),会进行数据备份和数据容灾。当你发现误操做或程序 bug 致使线上数据被误删或误改动时,必定不能慌乱,应及时与 DBA 联系,第一时间进行数据恢复(严重时直接中止服务),尽量减小影响和损失。对于重要数据(如资金)的操做,在开发时必定要反复进行测试,确保没有问题后再上线。

相关文章
相关标签/搜索