【MySQL】《高性能MySQL》学习笔记,第四章,Schema与数据类型优化

【MySQL】《高性能MySQL》学习笔记,第四章,Schema与数据类型优化

良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema。

反范式的设计可以加快某些类型的查询,单同时可能使另一类型的查询变慢,比如添加计数表和汇总表是一种很好的优化查询的方式,但这些表的维护成本可能会很高。

1.选择优化的数据类型

更小的通常更好。

? 应该尽量使用可以正确存储数据的最小类型,更小的数据类型通常更快,因为他们占用更少的磁盘,内存和CPU缓存,并且处理时需要的CPU周期更少。

简单就好

? 更简单的数据类型的操作通常需要更少的CPU周期。例如,整型数字比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较相对整型数字比较更复杂。比如,应使用INTERGER存储IP地址(inet_aton)

尽量避免NULL

? 通常情况下,最好指定列为NOT NULL。如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引,索引统计和值比较非常复杂,可为NULL的列会使用更多的存储空间,当可谓NULL的列被索引时,每个索引记录需要一个额外的字节。但是把可为NULL的列改成NOT NULL带来的性能提升比较小,但如果计划在列上创建索引,就应该避免设计成可为NULL的列。

1.1整数类型

整数类型 占用空间 范围
TINYINT 8 [-2^7,2^7-1]
SMALLINT 16 [-2^15,2^15-1]
MEDIUMINT 24 [-2^23,2^23-1]
INT 32 [-2^31,2^31-1]
BIGINT 64 [-2^63,2^63-1]

整型类型有可选的UNSIGNED属性,表示不允许负值,可以使原本正数的上线提高一倍。有符号和无符号类型使用相同的存储空间,并具有相同的性能。整型之间相互计算,是以64位的BIGINT作为中间类型进行计算的。

1.2实数类型

实数是带有小数部分的数字,可以使用DECIMAL存储比BIGINT还大的整数。

DECIMAL类型用于存储精确的小数,支持精确计算。例如,DECIMAL(18,9)小数点两边将各存储9个数字,一共使用9个字节,其中小数点前面的数字使用。DECIMAL最多允许65个数字。

浮点类型在存储同样范围的值时,通常比DECIMAL占用更少的空间,内部计算时采用DOUBLE作为计算类型。

因为需要额外的空间和计算开销,尽量只在对小鼠进行精确计算时才使用DECIMAL,在数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL,讲需要存储的货币单位根据小数的位数乘以相应的倍数即可。

1.3字符串类型

varchar

? varchar类型用于存储可变长字符串,比定长更节省空间,varchar需要使用1个或2个额外字节记录字符串的长度,如果列的最大长度小于或等于255个字节,则只是用1个字节表示,否则使用2个字节。varchar节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,如果在UPDATE时增加了该边长列的实际存储长度,这就导致需要额外的工作,如果一个行占用的空间增长,并且在页内没有更多的存储空间可以存储,在这种情况下,InnoDB需要分裂页来使行可以放进页内。

? varchar使用场合:1.字符串列的最大长度比平均长度大很多,列的更新很少

? 2.使用了UTF-8这种复合的字符集(每个字符都使用不同的字节数存储)

? MySQL在存储和检索时会保留varchar尾部的空格。InnoDB可以把过长的VARCHAR存储为BLOB。

char

? 定长字符串,MySQL在存储时会去除char尾部的空格。会造成“A ”与“A”产生唯一性冲突。数据如何存储取决于存储引擎,填充和截取空格的行为是在MySQL服务层进行的。

? 更长的列会消耗更高的内存,MySQL通常会分配固定大小的内存来保存内部值,尤其是使用内存临时表进行排序或操作总是会特别糟糕。

blob

? 采用二进制的方式存储,没有排序规则和字符集。包含tinyblob,blob,mediumblob,longblob

text

? 采用字符串的方式存储,有排序规则和字符集,包含tinytext,text,mediumtext,longtext。

与其他类型不同,MySQL把每个BLOB值和TEXT值当作一个独立的对象处理,存储引擎在存储时通常会做特殊处理,当BLOB和TEXT值太大时,InnoDB会使用专门的“外部”存储区域来存储,在原本的行中使用指针指向外部的存储区域。同事这两种数据格式最多只能建立前缀索引。

ENUM

? 枚举不推荐使用(想了解可以参考原书)

1.4日期和时间类型

DATETIME和TIMESTAMP

? 现在推荐使用DATETIME,范围更大,与时区无关,占用8个字节

1.5位数据类型

? InnoDB为每个BIT列使用一个足够存储的最小整数类型来存放,使用BIT类型并不能节省太多的存储空间,MySQL把BIT当作字符串类型,当检索BIT(1)的值时,结果是一个包含二进制0或者1的字符串。

2.MySQL 模式设计的陷阱

2.1 太多的列

? MySQL的存储引擎API在工作的时需要在服务器层和存储引擎层通过行缓冲格式拷贝数据,然后在服务器层将行缓冲内容解码成各个列。从行缓冲中将编码过的列转换成行结构的操作代价非常的高,转换的代价依赖于列的数量。

2.2太多的关联

? 一个粗略的经验法则,如果希望查询执行的快且并发性好,单个查询最好在12个表内做关联

2.3NULL值

? 需要存储一个事实上的“空值”到列表中时,可以使用0,某个特殊值,或者空字符串代替。MySQL会在索引中存储NULL值,而Oracle则不会。

3.范式和反范式

? 在范式化的数据库中,每个事实数据只会出现一次,

? 反范式化的数据库中,信息是冗余的,可能会存储在多个地方。

3.1范式化的优点和缺点

优点:

? 范式化的更新操作更快,只需要更改较少的数据。

? 范式化的表更小,可以更好的放在内存里,执行操作会更快。

? 没有多余的数据,可以减少distinct或GROUP BY的操作。

缺点:

? 通常需要关联,关联代价昂贵,也可能使一些索引策略无效。

3.2 反范式的优点和缺点

优点:

? 所有的数据都在一张表中,可以避免关联。

? 不关联的时候即使全表扫描,也是顺序IO。

缺点:

? 冗余的多余数据,更新更慢

? 表大,放到内存中,占用大,容易挤出热数据

4.更快的读,更慢的写

? 为了提升读查询的速度,经常会建一些额外索引,增加冗余列,甚至是创建缓存表和汇总表,这些方法会增加写查询的负担。

? 写操作变慢并不是读操作变得更快所付出的唯一代价,还可能同时增加了读操作和写操作的并发难度。

5.加快ALTER TABLE操作的速度

? ALTER TABLE操作对特大表来说,是个大问题。

? MySQL执行大部分修改表结构的步骤:

? 1.用新结构创建一个空表

? 2.从旧表中查出所有数据插入新表

? 3.删除旧表

? 一般而言,大部分ALTER TABLE操作将导致MySQL服务对该表的访问中断。

? 对于常见的场景,常见的技巧有两种:

? 1.现在一台不提供服务的机器上执行ALTER TABLE操作,然后切换

? 2.影子拷贝,即和原来的步骤一样,但是通过触发器的方式更新新表旧表数据,然后重命名

? 所有的MODIFY COLUMN操作,都会导致表重建。

5.1 只修改frm(表结构)文件

? 下面这些操作是有可能不需要重建的:

? 移除一个列的AUTO_INCREMENT属性

? 增加,移除,或更改ENUM和SET常量

? 步骤(本操作是火中取栗):

? 1.创建一张有相同结构的空表,进行所需要的修改

? 2.执行FLUSH TABLES WITH READ LOCK。关闭所有正在使用的表,并且禁止表被打开

? 3.交换frm文件

? 4.执行UNLOCK TABLES来释放第二步的读锁。

6.总结

? 1.避免设计过度复杂的数据库模式

? 2.使用小而简单的合适数据类型,尽可能避免使用NULL值

? 3.尽量使用相同的数据类型存储相似或者相关的值。

? 4.可变长字符串在临时表和排序时有可能悲观的按照最大长度分配内存。

? 5.尽量使用自增整数列定义主键

? 6.避免使用MySQL不再推荐的特性

? 7.谨慎对待BIT,ENUM,SET

?

?

?

?

?

原文地址:http://blog.51cto.com/l0vesql/2087197

时间: 2024-12-17 18:05:06

【MySQL】《高性能MySQL》学习笔记,第四章,Schema与数据类型优化的相关文章

高性能MySQL笔记 第4章 Schema与数据类型优化

4.1 选择优化的数据类型   通用原则 更小的通常更好 前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少. 简单就好 简单数据类型的操作需要更少的CPU周期. 尽量避免NULL 值可为NULL的列使得索引.索引统计和值比较都更复杂化.可为NULL的列会使用更多的存储空间. 整数类型 TINYINT SMALLINT MEDIUMINT INT BIGINT.分别使用8,16,24,32,64位存储空间.他们可以存储的值的范围从 -2

第四章:Schema与数据类型优化

1. 选择优化的数据类型 选择数据类型的原则 更小的通常更好:选择可以正确存储数据的最小数据类型 小的数据类型消耗更少的内存.CPU;占用更少的磁盘 选用简单的数据类型:简单的数据类型通常需要更少的CPU周期来处理 使用MySQL内建的类型来存储时间和日期 使用整型存储IP地址 尽量避免null值:通常情況下使用not null,除非真的需要存出null值 null值使得索引.索引統計.值比較都变得复杂 可为null的列需要更多的空间来存储 InnoBD使用单独的bit来存储null值 数字分为

高性能MySQL(四)—Schema与数据类型优化(1)

Schema与数据类型优化 选择优化的数据类型 下面是一些简单的原则: 更小的通常更好 一般情况下,应该尽量使用可以正确存储的最小数据类型.如:只需要存储0-200, tinyint unsigned就比较好.小的数据类型占的磁盘.内存和CPU缓存都较少,并且处理时需要的CPU周期数也更少. 简单就好 简单数据类型额操作通常需要更少的CPU周期.如:应该使用MySQL的內建类型来存储时间和日期而不是字符串.如:应该用整型存储IP地址. 尽量避免null 通常情况下最好指定列为NOT NULL,除

JavaScript学习笔记(第四章——第六章)

时间戳(2015-06-09 20:58:00) 第四章:变量.作用于和内存问题          typeof:判断元素是什么类型            instanceof:检测引用类型对象是否未指定类型          注:所有引用类型皆为Object的实例          JavaScript没有块级作用域:                    例1: if(true){ var color = “blue”; } alert(color);               // bl

Java学习笔记—第四章

第四章  变量和常量 1. Java的访问控制修饰符 使用访问控制修饰符可以限制数据的访问权限.访问控制修饰符有4个等级:private.protected.    public和默认(不指定修饰符). 类型/权限 private protected public 默认 所属类 可访问 可访问 可访问 可访问 同一个包中的其他类(包括子类) 不可访问 可访问 可访问 可访问 不同包中的子类 不可访问 可访问 可访问 不可访问 不同包中的非子类 不可访问 不可访问 可访问 不可访问 2. 变量:变

【PMP】Head First PMP 学习笔记 第四章

第四章 项目整合管理 项目经理每天的工作 力保项目顺利进行 紧密监督以确保计划进行 计划本身不完善需要予以修正 即使是更大的项目的子项目,也要有收尾的过程 6个整合管理过程 整合管理划分为6个过程,项目经理必须掌握的核心职责. 1.制订项目章程 授权你展开工作的文档,通常由赞助人(为项目提供资金的人)交给你. 2.制订项目管理计划 项目管理计划涵盖了所有知识领域,很大一部分就是告诉你在出现问题时如何处理变更. 3.指导和管理项目执行 确保所有人都在做他们本该做的事,项目创建的产品和项目确实满足干

Android学习笔记—第四章 Android开发组件2

第四章 Android开发组件2 列表类组件 (1)ListView组件:以垂直列表的形式列出需要显示的列表项 相关属性: a. android:divider  用于为列表视图设置分隔条,可以用颜色或者图片资源 b. android:dividerHeight  设置分隔条的高度 c. android:entries  通过数组资源为ListView指定列表项 d. android:footerDividersEnabled  设置是否在footerView之前绘制分隔条,默认为true. e

MySQL Cookbook学习笔记第四章

1,克隆表(创建一个恰好与某个已有表结构一致的表) create table - like克隆表结构:使用insert into - select语句克隆部分或者全部表数据 2,将查询结果保存到表中 a,使用insert into...select将语句查询结果插入表中,若表不存在需要使用create table -select 语句为查询结果新建一张表. insert into dst_tb1(i,s) select val, name from src_tb1 insert into dst

高性能mysql 第4章 Schema与数据类型优化

基本原则: 更小的通常更好:占用更少的磁盘 内存和cpu缓存. 简单就好:比如整形比字符型代价更低.使用日期型来存储日期而不是字符串.使用整形存储ip地址. 尽量避免null:如果可以 加上not null约束.因为可以null的列使索引,索引统计,值比较都变得复杂.通常把可为null的列改为not null带来的性能提升比较小,调优时没有必要首先修正这种情况来排查问题.但是如果计划在列上建立索引,如果可以保证是not null,那么尽量加上. 整数类型: tinyint,smallint.,m

《metasploit渗透测试魔鬼训练营》学习笔记第四章—web应用渗透

继续来学习metasploit...记好笔记是很重要的,下面开始正文: 二.WEB应用渗透技术 1.WEB应用渗透基础知识 先介绍WEB应用攻击的主要类型(大致介绍,具体请自行查询) Sql注入攻击:大致分为 普通注入和盲注 跨站脚本(XSS): 分为存储型XSS,反射性XSS以及DOM型XSS 跨站伪造请求(CSRF):以XSS方式注入一段脚本,受害者点击该脚本时,脚本伪造受害者发出请求. 会话认证管理缺陷:验证身份的功能存在缺陷. 安全误配置:开发和管理人员的失误导致存在漏洞. 不安全密码存