|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
主键类型的选择
尽可能使用整型 , 整型占用空间少 , 还可以设置为自动增长 。 尤其别使用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; 复制代码插入数据:
本文插图
它的索引结构大致是这样的:
本文插图
也就是说 , 索引列的顺序很重要 , 如果两行数据的Name列相同 , 则用Age列比较大小 , 如果Age列相同 , 则用Number列比较大小 。 先用第一列排序 , 然后是第二列 , 最后是第三列 。
查询的使用应该尽量从左往右匹配 , 另外 , 如果左边列范围查找 , 右边列无法使用索引;还有就是不能隔列查询 , 否则后面的索引也无法使用到 。 如以下几个SQL是正面范例:
- SELECT * from people where Name =’Abel’ and Age = 2 AND Number = 12312
- SELECT * from people where Name =’Abel’
- SELECT * from people where Name like ‘Abel%’
- SELECT * from people where Name = ‘Andy’ and Age BETWEEN 11 and 20
推荐阅读
- 数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?
- 小记|MySQL集群数据问题修复小记
- 通路|直播10分钟卖10万元,这家新通路联合仓是怎么做到的?
- 环球网|直播10分钟卖10万元,这家新通路联合仓是怎么做到的?
- |MySQL使用基础,这么用就对了
- |直播10分钟卖10万,这家新通路联合仓是怎么做到的?
- 科学|一个人10分钟能吞多少热狗?
- 5G|百瓦级闪充,满电10分钟!氮化镓概念欲展翅乘风?
- 手机|华为自研手机处理器或成绝唱?要想硬气还得掌握核心科技
- 手机|只有掌握了芯片技术,才能在移动市场占据先机,五大品牌你识几个