原文: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符号的语句要短的多。