原文:http://bbs.landingbj.com/t-0-244231-1.html

在任何一个数据库中,查询优化都是不可避免的一个话题。对于数据库工程师来说,优化工作是最有挑战性的工作。MySQL开源数据库也不例外。其 实笔者认为,数据库优化并没有大家所想象的那么苦难。通常情况下,大家可以从以下四个细节出发来做好MySQL数据库的查询优化工作。

 一、利用EXPLAIN关键字来评估查询语句中的缺陷


下图所示,现在笔者在数据库中执行了一条简单的Select查询语句,从一个表格中查询所有信息。现在数据库管理员想知道,数据库在执行这条语句时,做了
哪些工作?或者说想知道,这条查询语句有没有进一步优化的可能。如果要了解这个信息的话,就可以在查询语句中加入一个Explain关键字。

通过Select查询语句可以从数据库中查询某个表中的数据。但是这条语句执行的效率如何?是否还有优化的余地?这些内容是无法从上面这个简单的查询语句中获得的。为了了解更加详细的信息,需要加入Explain关键字。如下图所示:


入Explain关键字之后,系统并没有查询出表格中的数据,而只是显示了查询过程中的一些信息。这些信息对于我们后续进行数据库查询优化非常有帮助。从
上面这个信息中我们可以看出,用户只是进行来一个简单的查询。在这个查询中,没有用到任何索引、关键字等内容,也没有用到Where条件语句。为此这个查
询语句并不是很合理。虽然其可以找到最后正确的结果,不过其查询效率可能并不是很明显。为此数据库专家可以根据上面显示的信息来进行优化。如果我们现在在
查询语句中加入一条Where语句,那么又会有什么样的结果呢?如下图所示。

此时在最后一个Extra字段中,系统就会显
示已经使用了Where语句。在进行数据库优化���,我们需要抓住结果中的NULL字段或者空白内容的字段。这些地方往往是我们进行优化的重点。如上图
所示,我们可以给这条Select语句进行如下的优化:在表中设置关键字或者索引,来提高查询的效率。

 二、数据比较时采用相同类型的列以提高查询效率


数据查询时,有时候会在条件语句中加入判断的条件。如现在有两张表:用户基本信息表和用户权限表,两者通过用户编号作为关联。现在需要查询出每个用户对应
什么样的权限,此时就要通过用户编号作为查询条件来进行查询。现在假设用户基本信息表中的用户编号字段为CHAR类型的;而用户权限表中的用户编号是
VARCHAR类型的。这两个数据类型虽然都是字符型,但是不是同一种类型。现在对这连个表执行关联查询,其查询的效率如何呢?首先需要确定的一点是,虽
然他们两个是不同类型的字符型数据,不过是相互兼容的。最后仍然可以得到正确的结果。明确了这一点之后,我们再来考虑,能否对这个查询语句进行优化呢?


们再假设一下。现在这两个表的用户编号的数据类型都是CHAR。现在再对这两个表进行关联查询,得到的结果是否相同呢?我们测试的结果是,查询的结果是相
同的,但是其所花费的时间是不同的。而且随着数据量的增加,两个查询所相差的时间会越来越长。从这里可以知道,虽然这两个查询语句是等价的,但是其查询的
效率不同。

在MySQL数据库中,虽然相互兼容的数据类型可以进行相互比较。但是其查询的效率会有所影响。从提高数据库查
询效率的角度出发,笔者建议在查询条件语句中最好比较具有相同类型的列。在同等条件下,相同的列类型比不同类型的列能够提供更好的性能。特别是在数据量比
较多的数据库中,这尤其重要。

不过这个优化需要涉及到数据表的列类型。为此在数据表进行设计时,就需要考虑这一点。如针对
上面这个案例,我们可以在两个表中专门设置一个用户ID列。可以使用整数类型的序列,让系统进行自动编号。然后在查询时通过这个用户ID列来进行比较,而
不是通过原来的用户编号列进行比较。相对来说,这么操作查询的效率会更高。

  三、在Like关键字的起始处通配符要谨慎使用


实际工作中,笔者发现不少数据库管理员有一个不好的习惯。他们在使用Like等关键字时,通配符会乱用。如现在用户需要查找所有以“LOOK”为前缀的产
品信息。用户在查询时,会习惯性的使用下面的语句进行查询:like “%LOOK%”。这个条件语句会查询出所有品名中有LOOK这个单词的纪录,而不
是查询出以LOOK为前缀的产品信息。

虽然最终的结果可能是相同的。但是两者的查询效率不同。其实这很大一部分原因是客户端应用程序设计不当所造成的。如在客户端应用程序设计时,系统会默认显示一个%符号。如下图所示。


么设计的本意是好的,让系统能够支持模糊查询。但是用户在实际操作起来,就可以有问题。如用户在查询时,不会在%号前面输入LOOK这个单词,而是在%后
面输入LOOK这个单词。因为在查询时,光标会自动定位到%号后面。通常情况下,用户在输入时不会再去调整光标的位置。此时就出现了上面所说的这种情况。

为此笔者建议,在Like等关键字后面如果需要用到通配符的话,要非常的谨慎。特别是从大量数据中查找纪录时,这个通配符的位置一定要用对地方。在起始处能够不同通配符的话,尽量不要使用通配符。

 四、尽量使用其它形式来代替Like关键字


面提到在使用Like关键字时需要注意通配符的位置。其实从查询效率来看,我们不仅需要注意通配符的位置,而且能够不用Like关键字最好就不用。其实在
SQL语句中,可以利用其他方式来代替Like关键字。如现在有一个产品表,其编号为6位。现在需要查询以9开头的产品编号。这该怎么操作呢?

一是可以通过使用Like关键字,如LIKE “9%”。注意这个通配符的位置。这个条件语句可以查到所需要的结果。但是从性能优化的角度看,这条语句不是很好的处理方式。我们还可以通过一些折中的方式来实现。

二是通过比较符号来实现。如可以使用Value>=900000 and Value<=999999这种方式来实现。虽然两者的查询的结果是相同的。但是查询的时间这条语句要比上面这个采用Like符号的语句要短的多。

MySQL查询优化注意下面的四个细节的更多相关文章

  1. 我的MYSQL学习心得(十四) 备份和恢复

    我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...

  2. Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析

    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析     Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...

  3. MySQL查询优化之explain的深入解析

    在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...

  4. 1025WHERE执行顺序以及MySQL查询优化器

    转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...

  5. MySQL查询优化:查询慢原因和解决技巧

    在开发的朋友特别是和mysql有接触的朋友会碰到有时mysql查询很慢,当然我指的是大数据量百万千万级了,不是几十条了,下面我们来看看解决查询慢的办法. MySQL查询优化:查询慢原因和解决方法 会经 ...

  6. mysql查询优化器为什么可能会选择错误的执行计划

    有可能导致mysql优化器选择错误的执行计划的原因如下: A:统计信息不准确,mysql依赖存储引擎为其提供的统计信息来评估成本,然而有的存储引擎提供的信息是准确的,有的引擎提供的可能就偏差很大,如: ...

  7. mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

  8. Mysql查询优化器

    Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...

  9. MySQL查询优化 (一)

    以下的文章主要讲述的是MySQL查询优化的5个十分好用方法,熟悉SQL语句的人都清楚,如果要对一个任务进行操作的话,SQL语句可以有很多种相关写法,但是不同的写法查询的性能可能会有天壤之别. 本文列举 ...

随机推荐

  1. 怎样用命令行开启或关闭Windows服务

    怎样用命令行开启或关闭Windows服务 本篇博客主要包含一个内容: 怎样用命令行开启或关闭Windows服务 闲话少叙,直奔主题. 1.在桌面右击新建一个文本文档,然后打开. 2.找到需要开启或关闭 ...

  2. python3内置函数练习

    1. abs() abs() 函数返回数字的绝对值. print(abs(1.5236)) # 1.5236 print(abs(1.0)) # 1.0 2. all() all() 函数用于判断给定 ...

  3. python的shelve模块

    shelve shelve是一额简单的数据存储方案,他只有一个函数就是open(),这个函数接收一个参数就是文件名,并且文件名必须是.bat类型的.然后返回一个shelf对象,你可以用他来存储东西,就 ...

  4. Python3爬虫 利用百度地图api得到城市经纬度

    有2种方式,第一种是利用urllib , 方法1:利用urllib , 先把url 转成urlcode,然后读取网页,读到网页再用json读取内容,比较麻烦. 可以在浏览器输入,看一下格式. http ...

  5. 原生javascript实现回到顶部平滑滚动

    function rt() { var d = document, dd = document.documentElement, db = document.body, top = dd.scroll ...

  6. 分布式锁(一) Zookeeper分布式锁

    什么是Zookeeper? Zookeeper(业界简称zk)是一种提供配置管理.分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而 ...

  7. UVA1627-Team them up!(动态规划)

    Problem UVA1627-Team them up! Total Submissions:3577  Solved:648 Time Limit: 3000 mSec Problem Descr ...

  8. Linux 平台下 RMAN 全备 和 增量备份 shell 脚本

    转:http://blog.csdn.net/tianlesoftware/article/details/5740630 全备脚本 以 nocatalog 模式为例: Shell 脚本: ##### ...

  9. 小a与黄金街道 (欧拉函数)

    题意:a, b两个人在长度为n的一维数轴上(从1开始).a在1,b在n.每个人以1m/s的速度相向而行,则每一时刻存在坐标x,y,当cgd(n, x)==1,gcd(n, y)==1时,t1=k^x, ...

  10. jenkins使用2----基本实例

    一.配置 1.点击新建,选择构建自由风格 2.剩下的都不动,来到构建步骤,新增一个输出hell world 3.保存后点击立即构建 二.查看日志 4.点击构建历史,再点击控制台输出 5.第三行显示 临 ...