0

0

MySQL查询优化系列讲座之数据类型与效率_MySQL

php中文网

php中文网

发布时间:2016-06-01 14:12:37

|

1190人浏览过

|

来源于php中文网

原创

mysql优化mysql查询

AI脑图
AI脑图

AI一键生成思维导图

下载

  这一部分提供了如何选择数据类型来帮助提高查询运行速度的一些指导:
  
  在可以使用短数据列的时候就不要用长的。如果你有一个固定长度的CHAR数据列,那么就不要让它的长度超出实际需要。如果你在数据列中存储的最长的值有40个字符,就不要定义成CHAR(255),而应该定义成CHAR(40)。如果你能够用MEDIUMINT代替BIGINT,那么你的数据表就小一些(磁盘I/O少一些),在计算过程中,值的处理速度也快一些。如果数据列被索引了,那么使用较短的值带来的性能提高更加显著。不仅索引可以提高查询速度,而且短的索引值也比长的索引值处理起来要快一些。
  
  如果你可以选择数据行的存储格式,那么应该使用最适合存储引擎的那种。对于MyISAM数据表,最好使用固定长度的数据列代替可变长度的数据列。例如,让所有的字符列用CHAR类型代替VARCHAR类型。权衡得失,我们会发现数据表使用了更多的磁盘空间,但是如果你能够提供额外的空间,那么固定长度的数据行被处理的速度比可变长度的数据行要快一些。对于那些被频繁修改的表来说,这一点尤其突出,因为在那些情况下,性能更容易受到磁盘碎片的影响。
  
  · 在使用可变长度的数据行的时候,由于记录长度不同,在多次执行删除和更新操作之后,数据表的碎片要多一些。你必须使用OPTIMIZE TABLE来定期维护其性能。固定长度的数据行没有这个问题。
  
  · 如果出现数据表崩溃的情况,那么数据行长度固定的表更容易重新构造。使用固定长度数据行的时候,每个记录的开始位置都可以被检测到,因为这些位置都是固定记录长度的倍数,但是使用可变长度数据行的时候就不一定了。这不是与查询处理的性能相关的问题,但是它一定能够加快数据表的修复速度。
  
  尽管把MyISAM数据表转换成使用固定长度的数据列可以提高性能,但是你首先需要考虑下面一些问题:
  
  · 固定长度的数据列速度较快,但是占用的空间也较大。CHAR(n)列的每个值(即使是空值)通常占n个字符,这是因为把它存储到数据表中的时候,会在值的后面添加空格。VARCHAR(n)列占有的空间较小,因为只需要分配必要的字符个数用于存储值,加上一两个字节来存储值的长度。因此,在CHAR和VARCHAR列之间进行选择的时候,实际上是时间与空间的对比。如果速度是主要的考虑因素,那么就使用CHAR数据列获取固定长度列的性能优势。如果空间很重要,那么就使用VARCHAR数据列。总而言之,你可以认为固定长度的数据行可以提高性能,虽然它占用了更大的空间。但是对于某些特殊的应用程序,你可能希望使用两种方式来实现某个数据表,然后运行测试来决定哪种情况符合应用程序的需求。
  
  · 即使愿意使用固定长度类型,有时候你也没有办法使用。例如,长于255个字符的字符串就无法使用固定长度类型。
  
  MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系。两者都是作为CHAR类型处理的。
  
  对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列简单。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
  
  对于BDB数据表,无论使用固定长度或可变长度的数据列,差别都不大。两种方法你都可用试一下,运行一些实验测试来检测是否存在明显的差别。
  
  把数据列定义成不能为空(NOT NULL)。这会使处理速度更快,需要的存储更少。它有时候还简化了查询,因为在某些情况下你不需要检查值的NULL属性。
  
  考虑使用ENUM数据列。如果你拥有的某个数据列的基数很低(包含的不同的值数量有限),那么可以考虑把它转换为ENUM列。ENUM值可以被更快地处理,因为它们在内部表现为数值。
  
  使用PROCEDURE ANALYSE()。运行PROCEDURE ANALYSE()可以看到数据表中列的情况:
  
  SELECT * FROM tbl_name PROCEDURE ANALYSE();
  SELECT * FROM tbl_name PROCEDURE ANALYSE(16,256);
  
  输出的每一列信息都会对数据表中的列的数据类型提出优化建议。第二个例子告诉PROCEDURE ANALYSE()不要为那些包含的值多于16个或者256字节的ENUM类型提出建议。如果没有这样的限制,输出信息可能很长;ENUM定义通常很难阅读。
  
  根据的PROCEDURE ANALYSE()输出信息,你可能发现,可以修改自己的数据表来利用那些效率更高的数据类型。如果你决定改变某个数据列的类型,需要使用ALTER TABLE语句。
  
  使用OPTIMIZE TABLE来优化那些受到碎片影响的数据表。被大量修改的数据表,特别是那些包含可变长度数据列的表,容易遭受碎片的影响。碎片很糟糕,因为它会导致用于存储数据表的磁盘块形成无用空间(空洞)。随着时间的推移,为了得到有效的数据行,你必须读取更多的块,性能就会降低。这会出现在任何可变长度的数据行上,
  
  但是对于BLOB或TEXT数据列尤其突出,因为它们的长度差异太大了。在正常情况下使用OPTIMIZE TABLE会防止数据表的性能降低。OPTIMIZE TABLE可以用于MyISAM和BDB数据表,但是defragments只能用于MyISAM数据表。任何存储引擎中的碎片整理方法都是用mysqldump来转储(dump)数据表,接着使用转储的文件删除并重新建立那些数据表:
  
  % mysqldump --opt db_name tbl_name > dump.sql
  % mysql db_name   
  把数据打包放入BLOB或TEXT数据列。使用BLOB或TEXT数据列存储打包(pack)的数据,并在应用程序中进行解包(unpack),使你能够在一次检索操作中得到需要的任何信息,而不需要进行多次检索。它对那些很难用标准的数据表结构表现的数据值和频繁变化的数据值也是有帮助的。
  
  解决这个问题的另一种方法是让那些处理Web窗体的应用程序把数据打包成某种数据结构,然后把它插入到单个BLOB或TEXT数据列中。例如,你可以使用XML表示调查表回复,把那些XML字符串存储在TEXT数据列中。由于要对数据进行编码(从数据表中检索数据的时候还需要解码),它会增加客户端的开销,但是可以简化数据结构,而且它还消除了那些因为改变了调查表的内容而必须改变数据表结构的需求。
  
  另一方面,BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的"空洞",以后填入这些"空洞"的记录可能长度不同(前面讨论的OPTIMIZE TABLE提出解决这个问题的一些建议)。
  
  使用合成的(synthetic)索引。合成的索引列在某些时候是有用的。一种办法是根据其它的列的内容建立一个散列值,并把这个值存储在单独的数据列中。接下来你就可以通过检索散列值找到数据行了。但是,我们要注意这种技术只能用于精确匹配的查询(散列值对于类似=等范围搜索操作符是没有用处的)。我们可以使用MD5()函数生成散列值,也可以使用SHA1()或CRC32(),或者使用自己的应用程序逻辑来计算散列值。请记住数值型散列值可以很高效率地存储。同样,如果散列算法生成的字符串带有尾部空格,就不要把它们存储在CHAR或VARCHAR列中,它们会受到尾部空格去除的影响。
  
  合成的散列索引对于那些BLOB或TEXT数据列特别有用。用散列标识符值查找的速度比搜索BLOB列本身的速度快很多。
  
  在不必要的时候避免检索大型的BLOB或TEXT值。例如,SELECT *查询就不是很好的想法,除非你能够确定作为约束条件的WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。这也是BLOB或TEXT标识符信息存储在合成的索引列中对我们有所帮助的例子。你可以搜索索引列,决定那些需要的数据行,然后从合格的数据行中检索BLOB或TEXT值。
  
  把BLOB或TEXT列分离到单独的表中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行SELECT *查询的时候不会通过网络传输大量的BLOB或TEXT值。
  
  高效率地载入数据
  
  在大多数情况下,你所关注的是SELECT查询的优化,因为SELECT查询是最常见的查询类型,而且如何优化它们又不是太简单。与此形成对比,把数据载入数据库的操作就相对直接了。然而,你仍然可以利用某些策略来改善数据载入操作的效率。基本的原理如下所示:
  
  · 批量载入比单行载入的效率高,因为在每条
  
  记录被载入后,键缓存(key cache)不用刷新(flush);可以在这批记录的末尾刷新键缓存。键缓存刷新的频率减少得越多,数据载入的速度就越快。
  
  · 没有索引的数据表的载入速度比有索引的要快一些。如果存在索引,不但要把记录添加到数据文件中,还必须修改索引来反映新增的记录。
  
  · 较短的SQL语句比较长的SQL语句快,因为它们所涉及到服务器端分析过程较少,同时通过网络把它们从客户端发送到服务器上的速度也更快。
  
  其中有些因素看起来是次要的(尤其是最后一个),但是如果你载入的数据很多,那么即使很小的效率差异也会导致一定的性能差别。我们可以从前面的一般原理得出几条如何快速载入数据的实践结论:
  
  · LOAD DATA(所有形式的)比INSERT效率高,因为它是批量载入数据行的。服务器只需要分析和解释一条语句,而不是多条语句。同样,索引只需要在所有的数据行被处理过之后才刷新,而不是每行刷新一次。
  
  · 不带LOCAL的LOAD DATA比带有LOCAL的LOAD DATA的速度要快。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 5.8万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 9.3万人学习

Git 教程
Git 教程

共21课时 | 3.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号