解析MySQL数据库性能优化的六大技巧

 更新时间:2013年06月19日 12:00:18   作者:  
本篇文章是对MySQL数据库性能优化的六大技巧进行了详细的分析介绍,需要的朋友参考下
数据库表表面上存在索引和防错机制,然而一个简单的查询就会耗费很长时间。Web应用程序或许在开发环境中运行良好,但在产品环境中表现同样糟糕。如果你是个数据库管理员,你很有可能已经在某个阶段遇到上述情况。因此,本文将介绍对MySQL进行性能优化的技巧和窍门。

1.存储引擎的选择
如果数据表需要事务处理,应该考虑使用InnoDB,因为它完全符合ACID特性。如果不需要事务处理,使用默认存储引擎MyISAM是比较明智的。并且不要尝试同时使用这两个存储引擎。思考一下:在一个事务处理中,一些数据表使用InnoDB,而其余的使用MyISAM。结果呢?整个subject将被取消,只有那些在事务处理中的被带回到原始状态,其余的被提交的数据转存,这将导致整个数据库的冲突。然而存在一个简单的方法可以同时利用两个存储引擎的优势。目前大多数MySQL套件中包括InnoDB、编译器和链表,但如果你选择MyISAM,你仍然可以单独下载InnoDB,并把它作为一个插件。很简单的方法,不是吗?

2.计数问题
如果数据表采用的存储引擎支持事务处理(如InnoDB),你就不应使用COUNT(*)计算数据表中的行数。这是因为在产品类数据库使用COUNT(*),最多返回一个近似值,因为在某个特定时间,总有一些事务处理正在运行。如果使用COUNT(*)显然会产生bug,出现这种错误结果。

3.反复测试查询
查询最棘手的问题并不是无论怎样小心总会出现错误,并导致bug出现。恰恰相反,问题是在大多数情况下bug出现时,应用程序或数据库已经上线。的确不存在针对该问题切实可行的解决方法,除非将测试样本在应用程序或数据库上运行。任何数据库查询只有经过上千个记录的大量样本测试,才能被认可。

4.避免全表扫描
通常情况下,如果MySQL(或者其他关系数据库模型)需要在数据表中搜索或扫描任意特定记录时,就会用到全表扫描。此外,通常最简单的方法是使用索引表,以解决全表扫描引起的低效能问题。然而,正如我们在随后的问题中看到的,这存在错误部分。

5.使用”EXPLAIN”进行查询
当需要调试时,EXPLAIN是一个很好的命令,下面将对EXPLAIN进行深入探讨。
首先,创建一个简单的数据表:
复制代码 代码如下:

CREATETABLE'awesome_pcq'(
'emp_id'INT(10)NOTNULL
DEFAULT'0',
'full_name'VARCHAR(100)NOTNULL,
'email_id'VARCHAR(100)NOTNULL,
'password'VARCHAR(50)NOTNULL,
'deleted'TINYINT(4)NOTNULL,
PRIMARYKEY('emp_id')
) COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DEFAULT

这个数据表一目了然,共有五列,最后一列“deleted”是一个Boolean类变量flag来检查帐号是活动的还是已被删除。接下来,您需要用样本记录填充这个表(比如,100个雇员记录)。正如你看到的,主键是“emp_id”。因此,使用电子邮件地址和密码字段,我们可以很容易地创建一个查询,以验证或拒绝登录请求,如下(实例一):
复制代码 代码如下:

SELECTCOUNT(*)FROMawesome_pcqWHERE
email_id='blahblah'ANDpassword='blahblah'ANDdeleted=0

之前我们提到,要避免使用COUNT(*)。代码纠正如下(实例二):
复制代码 代码如下:

SELECTemp_idFROMawesome_pcqWHERE
email_id='blahblah'ANDpassword='blahblah'ANDdeleted=0

现在回想一下,在实例一中,代码查询定位并返回“email_id”和“password”等于给定值的行数。在实例二中,进行了同样的查询,不同的是明确要求列出“emp_id”所有满足给定的标准的值。哪个查询更费时?
很显然,这两个实例都是同样费时的数据库查询,因为无意间,两个实例查询都进行了全表扫描。为了更好地读懂指令,执行如下代码:
复制代码 代码如下:

EXPLAINSELECTemp_idFROMawesome_pcqWHERE
email_id='blahblah'ANDpassword='blahblah'ANDdeleted=0

在输出时,集中在倒数第二列:“rows”。假设我们已经将表填充了100个记录,它会在第一行显示100,这是MySQL需要进行扫描用来计算查询的结果的行数。这说明了什么?这需要全表扫描。为了克服这个弊端,则需要添加索引。

6.添加索引
先从重要的说起:给每一个可能遇到的次要问题创建索引并不明智。过多的索引会导致效能减慢和资源占用。在进一步讨论之前,在实例中创建一个样本索引:
复制代码 代码如下:

ALTERTABLE'awesome_pcq'ADDINDEX'LoginValidate'('email_id')

接下来,再次运行该查询:
复制代码 代码如下:

EXPLAINSELECTemp_idFROMawesome_pcqWHERE
email_id='blahblah'ANDpassword='blahblah'ANDdeleted=0

请注意运行后的值。不是100,而是1。因此,为了给出查询结果,MySQL只扫描了1行,多亏先前创建的索引。你可能会注意到,索引只在电子邮件地址字段创建,而查询对其他字段同样进行了搜索。这表明MySQL先执行了一个cros-check,检查是否有在WHERE子句中的定义的值有索引指定,如果有这样的值就执行相应的操作。

但是,它不是每次重复将减少到一个。例如,如果不是唯一的索引字段(如employee names列可以有两行相同的值),即使创建索引,也将有多个记录留下。但它仍然比全表扫描好。并且,在WHERE子句中指定列的顺序没有在这个过程中发挥作用。例如,如果在上面的查询中,改变字段的顺序,使电子邮件地址出现在最后,MySQL仍将遍历索引列的基础上。那么,就要在索引上动脑筋,注意如何避免大量的全表扫描,并获得更好的结果。不过,这需要经历一个很长的过程。

相关文章

  • MySQL 修改密码实例详解

    MySQL 修改密码实例详解

    这篇文章主要介绍了MySQL 修改密码实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • mysql实现查询结果导出csv文件及导入csv文件到数据库操作

    mysql实现查询结果导出csv文件及导入csv文件到数据库操作

    这篇文章主要介绍了mysql实现查询结果导出csv文件及导入csv文件到数据库操作,结合实例形式分析了mysql相关数据库导出、导入语句使用方法及操作注意事项,需要的朋友可以参考下
    2018-07-07
  • 可以改善mysql性能的InnoDB配置参数

    可以改善mysql性能的InnoDB配置参数

    MySQL与MSSQL 有一个区别在于MySQL建表的时候需要选择存储引擎,常用的存储引擎有MyISAM和InnoDB
    2011-05-05
  • mysql的左右内连接用法实例

    mysql的左右内连接用法实例

    这篇文章主要介绍了mysql的左右内连接用法,以一个完整实例较为详细的分析了mysql的左右内连接使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • MySQL常见的脚本语句格式参考指南

    MySQL常见的脚本语句格式参考指南

    无论是运维、开发、测试,还是架构师,数据库技术是一个必备加薪神器,下面这篇文章主要给大家介绍了关于MySQL常见的脚本语句格式参考指南的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • SQL去重方法汇总

    SQL去重方法汇总

    这篇文章主要给大家分享了SQL去重方法汇总,在使用SQL提数的时候,常会遇到表内有重复值的时候,比如我们想得到 uv (独立访客),就需要做去重。下面我们就来看看去重都有哪些方法吧
    2022-01-01
  • MySQL连接异常报10061错误问题解决

    MySQL连接异常报10061错误问题解决

    这篇文章主要介绍了MySQL连接异常报10061错误问题解决,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • MySQL 密码设置

    MySQL 密码设置

    本文介绍了如何修改一个用户的密码,你可以使用三种方法,GRANT语句、SET PASSWORD语句、直接修改授权表以及使用管理工具mysqladmin。
    2009-04-04
  • mysql创建表的sql语句详细总结

    mysql创建表的sql语句详细总结

    在本篇文章里小编给大家整理的是关于mysql创建表的sql语句的相关知识点,需要的朋友们可以参考下。
    2020-02-02
  • MySQL FLOAT不准问题解析

    MySQL FLOAT不准问题解析

    在数据库处理中,使用FLOAT类型存储浮点数时,由于二进制表示的限制,会导致精度损失,解决方法包括使用DOUBLE或DECIMAL类型来提高精度,或避免使用浮点数进行精确计算,感兴趣的可以了解一下
    2024-09-09

最新评论