数据类型及字节数参考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. 关闭 Identity 插入限制

    当为identity列插入时会报错: 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'xx'中的标识列指定显式值. 但在复制表数据时想带主键一起复制时,这时要设置IDEN ...

  2. Eclipse AmaterasUML 安装及使用

    AmaterasUML 对于我来说,是一个非常好用的UML插件. 用它来将我写过的一些Android程序进行逆工程非常好用,只不过,不能体现出包,这是一个小小的遗憾. 这个是它的主页地址:http:/ ...

  3. PowerDesigner 使用记录

    使用PowerDesigner 16.5 设计数据库表结构的操作过程: 第一步:打开PowerDesigner工具 第二步:创建一个新的数据模型,选择 File -> New Model -&g ...

  4. Qt 在控件上面绘图 label,pushbutton。。。。。

    最近有点时间,就研究研究Qt ,提升一下自己 我记得我在刚开始学习Qt 的时候,想要在一个控件上面绘制图形,那就要构建一个新类来调用该控件的绘图函数 今天看到了狗哥的学习博客,感觉自己好渺小啊,按照狗 ...

  5. 对 vscode 自动格式化的结果不太满意,我们该如何自己调整直至自己满意为止

    前提概述 采用vue-cli 3.0自动生成vue项目,选了ESlint+Prettier,在写request.js的时候,顺手用vscode右击格式化文件(Alt+Shift+F),一下子报了8个问 ...

  6. Drools 7.4.1.Final参考手册(八) 规则语言参考

    规则语言参考 概述 Drools有一个“本地”的规则语言.这种格式在标点符号上非常轻,并且通过“扩展器”支持自然语言和领域特定的语言,使语言能够变形到您的问题领域.本章主要与本机规则格式一致.用于表示 ...

  7. lintcode-108-分割回文串 II

    108-分割回文串 II 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. 样例 比如,给出字符串s = "aab", 返回 1, 因为 ...

  8. clientHeight & clientWidth & offsetHeight & offsetWidth & outerWidth & innerWidth & outerWidth & outerHeight

    clientHeight & clientWidth & offsetHeight & offsetWidth MDN https://developer.mozilla.or ...

  9. hdu 1856 More is better (并查集)

    More is better Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 327680/102400 K (Java/Others) ...

  10. [CF620E]New Year Tree

    题目大意:有一棵以$1$为根的有根树,有$n$个点,每个节点初始有颜色$c_i$.有两种操作: $1 v c:$将以$v$为根的子树中所有点颜色更改为$c$ $2 v:$ 查询以$v$为根的子树中的节 ...