基础
MySQL
MySQL
  • 基础知识
    • MySQL 的安装与配置
      • Windows
        • 安装
        • 配置文件
      • Linux
        • 安装
        • 配置文件
      • docker
      • mysql 配置文件格式
    • MySQL 查询的执行过程
      • MySQL 的客户端/服务器通信协议
      • MySQL 查询优化器
        • 优化器可能选择错误的执行计划
        • MySQL 能够处理的优化类型
          • 优化 COUNT()、MIN() 和 MAX()
          • 预估并转化为常数表达式
          • 提前终止查询
          • 排序优化
      • MySQL如何执行联接查询
    • 事务
      • ACID
      • 隔离级别
      • 死锁
      • 事务日志
      • 两阶段锁定协议
      • 多版本并发控制(MVCC)
  • SQL 优化
    • schema 设计
      • 选择数据类型
        • 整数类型
        • 实数类型
        • 字符串类型
          • VARCHAR 和 CHAR
          • BINARY 和 VARBINARY
          • BLOB 和 TEXT
          • ENUM 和 SET
        • 日期类型
      • 选择标识符
    • 索引
      • HASH 索引
      • B-tree 索引
      • 聚簇索引
      • 覆盖索引
      • 前缀索引和索引的选择性
      • 索引合并
      • 选择合适的索引列顺序
      • 使用索引扫描来做排序
      • 维护索引和表
    • 查询优化
      • 优化 SQL 语句的一般步骤
        • 1. 通过 show status 命令了解各种 SQL 的执行频率
        • 2. 定位执行效率较低的 SQL 语句
        • 3. 通过 EXPLAIN 分析低效 SQL 的执行计划
        • 4. 通过 SHOW PROFILE 分析 SQL
        • 5. 通过 TRACE 分析优化器如何选择执行计划
        • 6. 确定问题并采取相应的优化措施
      • 两个简单实用的优化方法
      • 一个复杂查询还是多个简单查询
      • 常用 SQL 的优化
        • 大批量插入数据
        • 优化 GROUP BY 语句
        • 优化联接查询
        • 优化分页查询
        • 优化 SQL_CALC_FOUND_ROWS
        • 优化 UNION 查询
    • Performance Schema
      • 配置
      • 使用
        • 检查SQL语句
        • 检查预处理语句
        • 语句剖析
        • 检查读写性能
        • 检查内存使用情况
        • 检查变量
    • MySQL线程
    • 复制
      • 概述
        • 复制中的各类文件
        • 三种复制格式
        • 全局事务标识符(GTID)
        • 崩溃后的复制安全
      • 安装
        • 基于二进制日志文件位置的复制
        • 基于GTID的复制
      • 复制拓扑
        • 主动/被动模式
        • 主动/只读池模式
        • 多级复制架构
  • 其他
    • 查询缓存
    • 批量insert
    • MySQL 锁的类型
    • MySQL 的索引有哪些
    • INSERT ... ON DUPLICATE KEY UPDATE Statement
由 GitBook 提供支持
在本页
  • 数据类型选择的原则
  • 更小的通常更好
  • 简单为好
  • 尽量避免存储 NULL
  • 数据类型选择的步骤
  • 1. 确定合适的大类型
  • 2. 选择具体类型
  1. SQL 优化
  2. schema 设计

选择数据类型

数据类型选择的原则

更小的通常更好

一般来说,尽量使用能够正确存储和表示数据的最小数据类型。更小的数据类型通常更快,因为它们占用的磁盘、内存和 CPU 缓存的空间更少,并且处理时需要的 CPU 周期也更少。

简单为好

简单数据类型的操作通常需要更少的 CPU 周期。

例如,整型数据比字符型数据的比较操作代价更低,因为字符集和排序规则(collation)使字符型数据的比较更复杂。

这里有两个例子:

  • 应该将日期和时间存储为 MySQL 的内置类型而不是字符串类型;

  • 应该用整型数据存储 IP 地址。

IPv4 地址的存储(无符号整数)

人们通常使用 VARCHAR(15) 列来存储 IP 地址。然而,IP 地址实际上是 32 位无符号整数,而不是字符串。用小数点将地址分成四段的表示方法只是为了让人们阅读容易,所以应该将 IP 地址存储为无符号整数。

MySQL 提供了 INET_ATON() 和 INET_NTOA() 函数来在这两种表示形式(整数和字符串)之间进行转换。使用的空间从 VARCHAR(15) 的约 16 字节缩减到无符号 32 位整数的 4 字节。

如果担心数据库的可读性,不想继续使用函数查看行数据,可以使用视图来简化数据查看的复杂性。

-- 准备数据
CREATE TABLE ip_test(
    ip INT UNSIGNED
);
INSERT INTO ip_test VALUES (INET_ATON("192.168.10.110"));

-- 查询
SELECT INET_NTOA(ip) FROM ip_test;
+--------------+
|INET_NTOA(ip) |
+--------------+
|192.168.10.110|
+--------------+

尽量避免存储 NULL

即使应用程序本身并不需要存储 NULL(缺失值),很多表也包含可为 NULL 的列,这是因为可为 NULL 是列的默认属性。通常情况下最好指定列为 NOT NULL,除非明确需要存储 NULL 值。

如果查询中包含可为 NULL 的列,对 MySQL 来说更难优化,因为可为 NULL 的列使得索引、索引统计和值比较都更复杂。可为 NULL 的列会使用更多的存储空间,在 MySQL 里也需要特殊处理。

通常把可为 NULL 的列改为 NOT NULL 带来的性能提升比较小,所以(调优时)没有必要首先在现有 schema 中查找并修改这种情况,除非确定这会导致问题。

数据类型选择的步骤

1. 确定合适的大类型

在为列选择数据类型时,第一步需要确定合适的大类型:数字、字符串、时间等。

2. 选择具体类型

下一步是选择具体类型。很多 MySQL 数据类型可以存储相同类型的数据,但在存储的值范围、表示的精度或者需要的物理空间(磁盘和内存)上存在着差异。相同大类型的不同子数据类型有时也有一些特殊的行为和属性。

例如,DATETIME 和 TIMESAMP 列可以存储相同类型的数据:时间和日期,精确到秒。然而 TIMESTAMP 只使用 DATETIME 一半的存储空间,还会根据时区变化,而且具有特殊的自动更新能力。另一方面,TIMESTAMP 允许的时间范围要小得多,有时候它的特殊能力会成为障碍。

上一页schema 设计下一页整数类型

最后更新于8个月前