数据类型及字节数参考http://www.cnblogs.com/qlqwjy/p/8590639.html

-------------------------表的优化:-----------------------

1: 定长与变长分离

如 id int, 占4个字节, char(4) 占4个字符长度,也是定长, time

即每一单元值占的字节是固定的.

核心且常用字段,宜建成定长,放在一张表.

而varchar, text,blob,这种变长字段,适合单放一张表, 用主键与核心表关联起来.

2:常用字段和不常用字段要分离.

需要结合网站具体的业务来分析,分析字段的查询场景,查询频度低的字段,单拆出来.

3:合理添加冗余字段.

防止后期修改表,在前期设计的时候就可以合理的添加冗余字段。

-----------------------列选择原则:------------------------

1.列类型优先级  

  整型>date,time>char,varchar>blob(存储从二进制文件)

列的特点分析:

整型: 定长,没有国家/地区之分,没有字符集的差异

time定长,运算快,节省空间. 考虑时区,写sql时不方便 where > ‘2005-10-12’;

enum: 能起来约束值的目的, 内部用整型来存储,但与char联查时,内部要经历串与值的转化

Char 定长, 考虑字符集和(排序)校对集

varchar, 不定长 要考虑字符集的转换与排序时的校对集,速度慢.

text/Blob 无法使用内存临时表
性别:  以utf8为例

char(1) , 3个字长字节

enum(‘男’,’女’);  // 内部转成数字来存,多了一个转换过程

tinyint() ,  // 0 1 2 // 定长1个字节.

2: 够用就行,不要慷慨 (如smallint,varchar(N))

原因: 大的字段浪费内存,影响速度,

以年龄为例 tinyint unsigned not null ,可以存储255岁,足够. 用int浪费了3个字节

以varchar(10) ,varchar(300)存储的内容相同, 但在表联查时,varchar(300)要花更多内存

3: 尽量避免用NULL()

原因: NULL不利于索引,要用特殊的字节来标注.

在磁盘上占据的空间其实更大.

实验:

可以建立2张字段相同的表,一个允许为null,一个不允许为Null,各加入1条,查看索引文件的大小. 可以发现,为null的索引要大些.(mysql5.5里,关于null已经做了优化,大小区别已不明显)

mysql> create database youhua;
Query OK, 1 row affected (0.11 sec) mysql> use youhua;
Database changed
mysql> create table t1(
-> name char(1) not null default '',
-> key(name)
-> )charset utf8;
Query OK, 0 rows affected (0.57 sec) mysql> create table t2(
-> name char(1),
-> key(name)
-> )charset utf8;
Query OK, 0 rows affected (0.56 sec)

通过explain分析查询:

不允许为null的长度为3:

mysql> explain select * from t1 where name='Q'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: ref
possible_keys: name
key: name
key_len: 3
ref: const
rows: 1
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)

允许null的索引长度为4:

mysql> explain select * from t2 where name='Q'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t2
partitions: NULL
type: ref
possible_keys: name
key: name
key_len: 4
ref: const
rows: 1
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)

  通过比较key_len发现null的索引大1.而且查询未null需要select * from t2 where name is null

4.Enum列的说明

1: enum列在内部是用整型来储存的

2: enum列与enum列相关联速度最快

3: enum列比(var)char 的弱势---在碰到与char关联时,要转化. 要花时间.

4: 优势在于,当char非常长时,enum依然是整型固定长度.

当查询的数据量越大时,enum的优势越明显.

5: enum与char/varchar关联 ,因为要转化,速度要比enum->enum,char->char要慢,

CREATE TABLE t3(
sex ENUM('male','female') DEFAULT 'male'
)CHARSET utf8; CREATE TABLE t4(
sex VARCHAR(6)
)CHARSET utf8;

插入两条数据:

mysql> insert into t3 values('male');
Query OK, 1 row affected (0.11 sec) mysql> insert into t4 values('male');
Query OK, 1 row affected (0.10 sec)

查询判断enum背后是整型:

mysql> select sex+1 from t3;
+-------+
| sex+1 |
+-------+
| 2 |
| 3 |
+-------+
2 rows in set (0.00 sec) mysql> select sex+1 from t4;
+-------+
| sex+1 |
+-------+
| 1 |
| 1 |
+-------+
2 rows in set, 2 warnings (0.00 sec)

但有时也这样用-----就是在数据量特别大时,可以节省IO.

列<---->列

时间

Enum<--->enum

10.53

Char<---->char

24.65

Enum<---->char

18.22

如果t2表的优势不明显, 加大t3的gender列 ,char(15), char(20)...

随着t3 gender列的变大,t2表优势逐渐明显.

原因----无论enum(‘manmaman’,’womanwomanwoman’) 枚举的字符多长,内部都是用整型表示, 在内存中产生的数据大小不变,而char型,却在内存中产生的数据越来越多.

总结: enum 和enum类型关联速度比较快,所以和enum对比的最好还是enum类型。

  Enum 类型 节省了IO

【mysql优化1】表的优化与列类型选择的更多相关文章

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

    转自http://isky000.com/database/mysql-perfornamce-tuning-schema MySQL 数据库性能优化之缓存参数优化 MySQL数据库性能优化之硬件瓶颈 ...

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

    殊不知,在N年前被奉为"圣经"的数据库设计3范式早就已经不完全适用了.这里我整理了一些比较常见的数据库表结构设计方面的优化技巧,希望对大家有用. 由于MySQL数据库是基于行(Ro ...

  3. MySQL优化三 表结构优化

    由于MySQL数据库是基于行(Row)存储的数据库,而数据库操作 IO 的时候是以 page(block)的方式,也就是说,如果我们每条记录所占用的空间量减小,就会使每个page中可存放的数据行数增大 ...

  4. MySQL优化之表结构优化的5大建议

    很多人都将 数据库设计范式 作为数据库表结构设计“圣经”,认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求殊不知,在N年前被奉为“圣经”的数据库设计 ...

  5. Mysql 建表时,日期时间类型选择

    mysql(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示  D ...

  6. MySQL建表时,日期时间类型选择

    MySQL(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示  D ...

  7. MySQL列类型选择

    比如年龄这个字段可以使用  1990-03-15  也可以用  19900315表示在列类型上可以选择 char 和 int:如果一个字段可以选择多种类型,尽量选择一个更快的类型:字段类型优先级   ...

  8. mysql千万级表关联优化

    MYSQL一次千万级连表查询优化(一) 概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差 ...

  9. mysql千万级表关联优化(2)

    概述: 交代一下背景,这算是一次项目经验吧,属于公司一个已上线平台的功能,这算是离职人员挖下的坑,随着数据越来越多,原本的SQL查询变得越来越慢,用户体验特别差,因此SQL优化任务交到了我手上. 这个 ...

随机推荐

  1. 用链表实现nodejs的内存对象管理

    虽然javascript拥有垃圾收集,但是垃圾收集机制并不会自动释放持久对象,比如websocks连接. 为了能够在某些特定情况下中止一些连接(比如内存不足),显然要建立全局的对象管理器进行管理. 显 ...

  2. iFIERO - (二)宇宙大战 Space Battle -- SpriteKit 无限循环背景Endless、SpriteKit物理碰撞、CoreMotion加速计

    本节主要讲解如何创建无限循环Endless的星空背景(如下图).玩家飞船发射子弹,监测子弹击外星敌机的SpriteKit物理碰撞并消灭敌机,以及应用iOS的CoreMotion加速计移动飞船躲避外星敌 ...

  3. CSS3 : transform 与 transform-origin 属性可以使元素样式发生转变

    CSS3 : transform 用于元素样式的转变,比如使元素发生位移.角度变化.拉伸缩小.按指定角度歪斜 transform结合transition可实现各类动画效果 transform : tr ...

  4. Python全栈 正则表达式(概念、、语法、元字符、re模块)

    前言:        普通人有三件东西看不懂:医生的处方,道士的鬼符,程序员得正则表达式       什么是正则表达式? 正则表达式,又称规则表达式,英文名为Regular Expression,在代 ...

  5. python 基础篇 13 迭代器与生成器

    13. 前⽅⾼能-迭代器和⽣成器本节主要内容:1. 迭代器2. ⽣成器 ⼀. 迭代器我们之前⼀直在⽤可迭代对象进⾏迭代操作. 那么到底什么是可迭代对象. 本⼩节主要讨论可迭代对象. ⾸先我们先回顾⼀下 ...

  6. Django源码分析之权限系统_擒贼先擒王

    乍见 Django内置的权限系统已经很完善了,加上django-guardian提供的功能,基本上能满足大部分的权限需求.暂且不说django-guardian,我们先来看下Django内置的权限系统 ...

  7. DFS(1)——hdu1518Square

    一.题目回顾 题目链接:Square 题意:给你M根木棒,请判断这些木棒能否组成正方形. 二.解题思路 DFS+剪枝 [变量说明] sum:木棒的总长度 ave:形成的正方形的边长 maxlen:最长 ...

  8. beta版本冲刺七

    目录 组员情况 组员1:胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:何宇恒 组员11:刘一好 展示组内最新 ...

  9. ExtJS6.0扩展日期选择控件为也可以选择时间

    PS:ExtJS自带的日期选择控件只能够选择日期,但是现在的需求需要精确到秒,所以在网上搜索了一些例子(大部分是4.0的)作为参考,然后改出了6.0可用的一个日期时间选择控件. 1.找到extjs6. ...

  10. postman工具中如何提取接口的返回值

    提取接口返回值   当返回值是返回JSON时 1.let json = JSON.parse(responseBody); // responseBody是包含整个返回内容的字符串 提取某字段的值: ...