技术开发 频道

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

  5、使用”EXPLAIN”进行查询

  当需要调试时,EXPLAIN是一个很好的命令,下面将对EXPLAIN进行深入探讨。

  首先,创建一个简单的数据表:

CREATE TABLE 'awesome_pcq' (
'emp_id' INT(10) NOT NULL
DEFAULT '0' ,
'full_name' VARCHAR(100) NOT NULL ,
'email_id' VARCHAR(100) NOT NULL ,
'password' VARCHAR(50) NOT NULL ,
'deleted' TINYINT(4) NOT NULL ,
PRIMARY KEY ('emp_id')
) COLLATE
= 'utf8_general_ci'
ENGINE
= InnoDB
ROW_FORMAT
= DEFAULT

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

SELECT COUNT (*) FROM awesome_pcq WHERE
email_id
= 'blahblah' AND password = 'blahblah' AND deleted = 0

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

SELECT emp_id FROM awesome_pcq WHERE
email_id
= 'blahblah' AND password = 'blahblah' AND deleted = 0

  现在回想一下,在实例一中,代码查询定位并返回“email_id”和“password”等于给定值的行数。在实例二中,进行了同样的查询,不同的是明确要求列出“emp_id”所有满足给定的标准的值。哪个查询更费时?

  很显然,这两个实例都是同样费时的数据库查询,因为无意间,两个实例查询都进行了全表扫描。为了更好地读懂指令,执行如下代码:

EXPLAIN SELECT emp_id FROM awesome_pcq WHERE
email_id
= 'blahblah' AND password = 'blahblah' AND deleted = 0

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

  6、添加索引

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

ALTER TABLE 'awesome_pcq' ADD INDEX 'LoginValidate' ('email_id')

  接下来,再次运行该查询:

EXPLAIN SELECT emp_id FROM awesome_pcq WHERE
email_id
= 'blahblah' AND password = 'blahblah' AND deleted = 0

  请注意运行后的值。不是100,而是1。因此,为了给出查询结果,MySQL只扫描了1行,多亏先前创建的索引。你可能会注意到,索引只在电子邮件地址字段创建,而查询对其他字段同样进行了搜索。这表明MySQL先执行了一个cros-check,检查是否有在WHERE子句中的定义的值有索引指定,如果有这样的值就执行相应的操作。但是,它不是每次重复将减少到一个。例如,如果不是唯一的索引字段(如employee names列可以有两行相同的值),即使创建索引,也将有多个记录留下。但它仍然比全表扫描好。并且,在WHERE子句中指定列的顺序没有在这个过程中发挥作用。例如,如果在上面的查询中,改变字段的顺序,使电子邮件地址出现在最后,MySQL仍将遍历索引列的基础上。那么,就要在索引上动脑筋,注意如何避免大量的全表扫描,并获得更好的结果。不过,这需要经历一个很长的过程。

0
相关文章