`
Sobfist
  • 浏览: 31550 次
  • 性别: Icon_minigender_1
  • 来自: 邯郸
社区版块
存档分类
最新评论

MySQL表结构优化

 
阅读更多
前言

     很多人都将<数据库设计范式>作为数据库表结构设计“圣经”,认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求。殊不知,在N年前被奉为“圣经”的数据库设计3范式早就已经不完全适用了。这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用。

     由于MySQL数据库是基于行(Row)存储的数据库,而数据库操作 IO 的时候是以 page(block)的方式,也就是说,如果我们每条记录所占用的空间量减小,就会使每个page中可存放的数据行数增大,那么每次 IO 可访问的行数也就增多了。反过来说,处理相同行数的数据,需要访问的 page 就会减少,也就是 IO 操作次数降低,直接提升性能。此外,由于我们的内存是有限的,增加每个page中存放的数据行数,就等于增加每个内存块的缓存数据量,同时还会提升内存换中数据命中的几率,也就是缓存命中率。



数据类型选择

  数据库操作中最为耗时的操作就是 IO 处理,大部分数据库操作 90% 以上的时间都花在了 IO 读写上面。所以尽可能减少 IO 读写量,可以在很大程度上提高数据库操作的性能。

  我们无法改变数据库中需要存储的数据,但是我们可以在这些数据的存储方式方面花一些心思。下面的这些关于字段类型的优化建议主要适用于记录条数较多,数据量较大的场景,因为精细化的数据类型设置可能带来维护成本的提高,过度优化也可能会带来其他的问题:

  1.数字类型:非万不得已不要使用DOUBLE,不仅仅只是存储长度的问题,同时还会存在精确性的问题。同样,固定精度的小数,也不建议使用DECIMAL,建议乘以固定倍数转换成整数存储,可以大大节省存储空间,且不会带来任何附加维护成本。对于整数的存储,在数据量较大的情况下,建议区分开 TINYINT / INT / BIGINT 的选择,因为三者所占用的存储空间也有很大的差别,能确定不会使用负数的字段,建议添加unsigned定义。当然,如果数据量较小的数据库,也可以不用严格区分三个整数类型。

  2.字符类型:非万不得已不要使用 TEXT 数据类型,其处理方式决定了他的性能要低于char或者是varchar类型的处理。定长字段,建议使用 CHAR 类型,不定长字段尽量使用 VARCHAR,且仅仅设定适当的最大长度,而不是非常随意的给一个很大的最大长度限定,因为不同的长度范围,MySQL也会有不一样的存储处理。

  3.时间类型:尽量使用TIMESTAMP类型,因为其存储空间只需要 DATETIME 类型的一半。对于只需要精确到某一天的数据类型,建议使用DATE类型,因为他的存储空间只需要3个字节,比TIMESTAMP还少。不建议通过INT类型类存储一个unix timestamp 的值,因为这太不直观,会给维护带来不必要的麻烦,同时还不会带来任何好处。

  4.ENUM & SET:对于状态字段,可以尝试使用 ENUM 来存放,因为可以极大的降低存储空间,而且即使需要增加新的类型,只要增加于末尾,修改结构也不需要重建表数据。如果是存放可预先定义的属性数据呢?可以尝试使用SET类型,即使存在多种属性,同样可以游刃有余,同时还可以节省不小的存储空间。

  5.LOB类型:强烈反对在数据库中存放 LOB 类型数据,虽然数据库提供了这样的功能,但这不是他所擅长的,我们更应该让合适的工具做他擅长的事情,才能将其发挥到极致。在数据库中存储 LOB 数据就像让一个多年前在学校学过一点Java的营销专业人员来写 Java 代码一样。



字符编码

  字符集直接决定了数据在MySQL中的存储编码方式,由于同样的内容使用不同字符集表示所占用的空间大小会有较大的差异,所以通过使用合适的字符集,可以帮助我们尽可能减少数据量,进而减少IO操作次数。

  1.纯拉丁字符能表示的内容,没必要选择 latin1 之外的其他字符编码,因为这会节省大量的存储空间。

  2.如果我们可以确定不需要存放多种语言,就没必要非得使用UTF8或者其他UNICODE字符类型,这回造成大量的存储空间浪费。

  3.MySQL的数据类型可以精确到字段,所以当我们需要大型数据库中存放多字节数据的时候,可以通过对不同表不同字段使用不同的数据类型来较大程度减小数据存储量,进而降低 IO 操作次数并提高缓存命中率。



适当拆分

  有些时候,我们可能会希望将一个完整的对象对应于一张数据库表,这对于应用程序开发来说是很有好的,但是有些时候可能会在性能上带来较大的问题。

  当我们的表中存在类似于 TEXT 或者是很大的 VARCHAR类型的大字段的时候,如果我们大部分访问这张表的时候都不需要这个字段,我们就该义无反顾的将其拆分到另外的独立表中,以减少常用数据所占用的存储空间。这样做的一个明显好处就是每个数据块中可以存储的数据条数可以大大增加,既减少物理 IO 次数,也能大大提高内存中的缓存命中率。

  上面几点的优化都是为了减少每条记录的存储空间大小,让每个数据库中能够存储更多的记录条数,以达到减少 IO 操作次数,提高缓存命中率。下面这个优化建议可能很多开发人员都会觉得不太理解,因为这是典型的反范式设计,而且也和上面的几点优化建议的目标相违背。



适度冗余

  为什么我们要冗余?这不是增加了每条数据的大小,减少了每个数据块可存放记录条数吗?

  确实,这样做是会增大每条记录的大小,降低每条记录中可存放数据的条数,但是在有些场景下我们仍然还是不得不这样做:

  1.被频繁引用且只能通过 Join 2张(或者更多)大表的方式才能得到的独立小字段。

  2.这样的场景由于每次Join仅仅只是为了取得某个小字段的值,Join到的记录又大,会造成大量不必要的 IO,完全可以通过空间换取时间的方式来优化。不过,冗余的同时需要确保数据的一致性不会遭到破坏,确保更新的同时冗余字段也被更新。



尽量使用 NOT NULL

  NULL 类型比较特殊,SQL 难优化。虽然 MySQL NULL类型和 Oracle 的NULL 有差异,会进入索引中,但如果是一个组合索引,那么这个NULL 类型的字段会极大影响整个索引的效率。此外,NULL 在索引中的处理也是特殊的,也会占用额外的存放空间。

  很多人觉得 NULL 会节省一些空间,所以尽量让NULL来达到节省IO的目的,但是大部分时候这会适得其反,虽然空间上可能确实有一定节省,倒是带来了很多其他的优化问题,不但没有将IO量省下来,反而加大了SQL的IO量。所以尽量确保 DEFAULT 值不是 NULL,也是一个很好的表结构设计优化习惯。(此文为转载)
分享到:
评论

相关推荐

    mysql表结构导出jar包

    总之,MySQL表结构的导出是一个常见的需求,可以使用MySQL自带的`mysqldump`工具或第三方软件如"database-export-3.2.0-SNAPSHOT.jar"来完成。选择哪种方式取决于个人或团队的需求,如自动化程度、便利性以及是否...

    Java自动生成Mysql数据库结构

    通过加载数据库驱动,建立数据库连接,执行SQL语句,然后处理返回的结果集,开发者可以实现各种数据库操作,包括获取表结构信息。 自动化的数据库结构生成可以极大地提高开发效率。通常,数据库设计是项目初期的...

    同步mysql表结构.zip

    "同步MySQL表结构"这个主题涉及到的是数据库管理中的一个重要环节,即如何在不同的MySQL实例之间保持表结构的一致性。当我们需要在开发、测试和生产环境之间迁移数据,或者在多个服务器之间复制数据库时,表结构的...

    藏经阁-MySQL表和索引优化实战-11页

    1. 表结构优化:合理设计表结构,选择合适的数据类型,尽量减少存储空间占用。 2. 索引优化:合理设计索引,选择合适的索引类型和字段,尽量提高查询效率。 3. 查询优化:合理设计查询语句,选择合适的查询方式,...

    MYSQL数据库表结构优化方法详解

    本文实例讲述了MYSQL数据库表结构优化方法。分享给大家供大家参考,具体如下:  选择合适的数据类型  1、使用可以存下你的数据的最小的数据类型  2、使用简单的数据类型。Int要比varchar类型在mysql处理上简单 ...

    mysql性能优化.pptx

    MySQL性能优化是一个涵盖广泛的主题,涉及多个层面,包括SQL语句优化、索引优化、数据库表结构优化、系统级配置优化以及服务器硬件优化。以下是对这些方面进行详细说明: 1. **SQL语句优化** - **慢查询日志**:...

    Navicat 实现同步sqlserver表结构到mysql操作手册1

    本文将详细介绍如何使用Navicat工具实现SQL Server表结构到MySQL的同步操作,这对于那些需要在不同数据库系统间进行数据迁移的开发者来说尤其有用。 Navicat是一款强大的数据库管理工具,支持多种数据库类型,包括...

    MySQL数据库性能优化之表结构优化

     这是 MySQL数据库性能优化专题 系列的第二篇文章:MySQL 数据库性能优化之表结构优化  系列的第一篇文章:MySQL 数据库性能优化之缓存参数优化  由于MySQL数据库是基于行(Row)存储的数据库,而数据库操作 IO ...

    Mysql表索引优化与底层数据结构深入剖析

    Mysql表索引优化与底层数据结构深入剖析

    千金良方:MySQL性能优化金字塔法则.docx

    MySQL性能优化是指通过调整MySQL数据库的配置、优化数据库结构和查询语句等方式,提高MySQL数据库的性能和响应速度,以满足应用程序的需求。MySQL作为最流行的开源数据库之一,被广泛应用于各种规模的企业和应用程序...

    设计 MySQL 表结构 - NineData.pdf

    在设计 MySQL 表结构时,NineData 提供了一个强大的可视化工具,使得用户无需手动编写 SQL 命令,只需通过鼠标操作即可完成整个过程。这个功能适用于 MySQL、MariaDB 和 OceanBase 数据源,大大简化了数据库开发者的...

    MySQL修改表结构.doc

    在MySQL数据库中,修改表结构是一项常见的操作,用于适应数据模型的变化或优化表的设计。本文主要探讨了如何在已有数据的情况下安全地修改表的字段类型、约束条件、字段位置以及字段名称,同时强调了在执行这些操作...

    mysql性能的优化

    MySQL性能优化是一个综合性的过程,涉及到SQL查询优化、数据库结构优化以及MySQL服务器配置等多个方面。通过上述方法和技术的应用,可以显著提高MySQL的运行效率,降低资源消耗,最终实现更好的用户体验和服务质量。

    mysql5.6性能优化

    具体而言,优化可以从多个层面入手,包括但不限于查询优化、数据库结构优化以及服务器优化等方面。 #### 二、数据库性能参数 在MySQL中,可以通过`SHOW STATUS`命令来查看一系列有关数据库性能的参数。这些参数...

    mysql优化笔记+资料

    1. 定期分析和优化表(ANALYZE TABLE和OPTIMIZE TABLE)以更新统计信息和物理结构。 2. 清理不再使用的旧数据,避免数据膨胀。 3. 监控数据库性能,使用工具如MySQL Performance Schema或Percona Toolkit进行诊断。 ...

    MySQL数据库的优化

    MySQL介绍、架构、什么优化、查询优化、索引使用、存储优化、数据库结构优化、硬件优化、MySQL缓存、MySQL服务器参数

    MySQL大表性能优化方案 和 MySQL高性能表设计规范

    通过合理的表结构设计、索引优化、查询优化以及内存和存储管理,我们可以有效地应对大数据量带来的挑战,实现数据库的高效运行。在实践中,我们需要根据具体业务需求和资源限制,灵活应用这些策略和规范,以达到最优...

    MySQL优化之表结构优化的5大建议(数据类型选择讲的很好)

    以下是一些针对MySQL表结构优化的建议: 1. **数据类型选择**: - 数字类型:避免使用`DOUBLE`类型,因为它不仅占存储空间,而且可能导致精度问题。对于固定精度的小数,推荐将数值乘以固定倍数后转为整数存储,...

    Navicat客户端sqlserver表结构转到mysql数据库中操作文档

    本操作文档将详细介绍如何使用Navicat客户端工具将SQL Server的表结构转换到MySQL数据库中。Navicat是一款强大的数据库管理工具,支持多种数据库系统,包括SQL Server和MySQL,使得数据迁移变得简单而高效。 首先,...

Global site tag (gtag.js) - Google Analytics