|10分钟掌握MySQL的索引查询优化技巧( 二 )


char的实际占用空间是固定的 , 当表中字符串数据的长度相差无几或很短时适合使用chart类型 。
与varchar和char对应的有varbinary和binary , 后者存储的是二进制字符串 , 和前者相比 , 后者大小写敏感 , 不用考虑编码方式 , 执行比较操作时更快 。
需要注意的是:虽然varchar(5)和varchar(200)在存储“hello”这个字符串时使用相同的存储空间 , 但并不意味着将varchar的长度设置太大不会影响性能 , 实际上 , MySQL的某些内部计算 , 比如创建内存临时表时(某些查询会导致MySQL自动创建临时表) , 会分配固定大小的空间存放数据 。
blob使用二进制字符串保存大文本 , text使用字符保存大文本 , InnoDB会使用专门的外部存储区来存放此类数据 , 数据行内仅存放指向他们的指针 , 此类数据不宜创建索引(要创建也只能正对字符串前缀创建) , 不过也不会有人这么干 。
如果某列字符串大量重复且内容有限 , 可使用枚举代替 , MySQL处理枚举时维护了一个“数字-字符串”表 , 使用枚举可以减少很多存储空间 。
时间类型

  • year
  • date
  • time
  • datetime
  • timestamp
datetime存储范围是1001到9999 , 精确到秒 。 timestamp存储1970年1月1日午夜以来的秒数 , 可以表示到2038年 。 占用4个字节 , 是datetime占用空间的一半 。 timestamp表示的时间和时区有关 , 另外timestamp列还有个特性 , 执行insert或update语句时 , MySQL会自动更新第一个类型为timestamp的列的数据为当前时间 。 很多表中都有设计有一列叫做UpdateTime , 这个列使用timestamp倒是挺合适的 , 会自动更新 , 前提是系统不会使用到2038年 。
主键类型的选择
尽可能使用整型 , 整型占用空间少 , 还可以设置为自动增长 。 尤其别使用GUID , MD5等哈希值字符串作为主键 , 这类字符串随机性很大 , 由于InnoDB主键默认是聚簇索引列 , 所以导致数据存储太分散 。 另外 , InnoDB的二级索引列中默认包含主键列 , 如果主键太长 , 也会使得二级索引很占空间 。
特殊类型的数据
存储IP最好使用32位无符号整型 , MySQL提供了函数inet_aton()和inet_ntoa()进行IP地址的数字表示和字符串表示之间的转换 。
索引优化
InnoDB使用B+树实现索引 , 举个例子 , 假设有个People , 建表语句如下
CREATE TABLE `people` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(5) NOT NULL, `Age` tinyint(4) NOT NULL, `Number` char(5) NOT NULL COMMENT '编号', PRIMARY KEY (`Id`), KEY `i_name_age_number` (`Name`,`Age`,`Number`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8; 复制代码插入数据:
|10分钟掌握MySQL的索引查询优化技巧
本文插图

它的索引结构大致是这样的:
|10分钟掌握MySQL的索引查询优化技巧
本文插图

也就是说 , 索引列的顺序很重要 , 如果两行数据的Name列相同 , 则用Age列比较大小 , 如果Age列相同 , 则用Number列比较大小 。 先用第一列排序 , 然后是第二列 , 最后是第三列 。
查询的使用应该尽量从左往右匹配 , 另外 , 如果左边列范围查找 , 右边列无法使用索引;还有就是不能隔列查询 , 否则后面的索引也无法使用到 。 如以下几个SQL是正面范例: