首页 > 代码库 > MySQL之查询优化方式(笔记)
MySQL之查询优化方式(笔记)
1.COUNT()
对COUNT的优化可以通过下面的SQL实现
mysql> select count(gnp<10000 or null) as ‘<<<<‘,count(gnp>=10000 or null) as ‘>>>>‘ from country;+------+------+| <<<< | >>>> |+------+------+| 152 | 87 |+------+------+1 row in set (0.00 sec)
count(*)与count(cloumn)返回的值可能不一样,因为如果存在空的情况,count(*)也会计算在内
2.SUM()
对SUM()的优化需要通过建立索引实现
mysql> desc city;+-------------+----------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------------+----------+------+-----+---------+----------------+| ID | int(11) | NO | PRI | NULL | auto_increment || Name | char(35) | NO | MUL | | || CountryCode | char(3) | NO | | | || District | char(20) | NO | | | || Population | int(11) | NO | | 0 | |+-------------+----------+------+-----+---------+----------------+5 rows in set (0.03 sec)mysql> create index popu_index on city(population);Query OK, 4079 rows affected (0.05 sec)Records: 4079 Duplicates: 0 Warnings: 0mysql> explain select SUM(population) as sum from city;+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+| 1 | SIMPLE | city | index | NULL | popu_index | 4 | NULL | 4079 | Using index |+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+1 row in set (0.00 sec)mysql> select SUM(population) as sum from city;+------------+| sum |+------------+| 1429559884 |+------------+1 row in set (0.00 sec)
3.子查询的优化
对于子查询的优化可以通过on实现
mysql> desc city;+-------------+----------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+-------------+----------+------+-----+---------+----------------+| ID | int(11) | NO | PRI | NULL | auto_increment || Name | char(35) | NO | MUL | | || CountryCode | char(3) | NO | | | || District | char(20) | NO | | | || Population | int(11) | NO | MUL | 0 | |+-------------+----------+------+-----+---------+----------------+5 rows in set (0.01 sec)mysql> desc country;;+----------------+---------------------------------------------------------------------------------------+------+-----+---------+--| Field | Type | Null | Key | Default | E+----------------+---------------------------------------------------------------------------------------+------+-----+---------+--| Code | char(3) | NO | PRI | || Name | char(52) | NO | | || Continent | enum(‘Asia‘,‘Europe‘,‘North America‘,‘Africa‘,‘Oceania‘,‘Antarctica‘,‘South America‘) | NO | | Asia || Region | char(26) | NO | | || SurfaceArea | float(10,2) | NO | | 0.00 || IndepYear | smallint(6) | YES | | NULL || Population | int(11) | NO | | 0 || LifeExpectancy | float(3,1) | YES | | NULL || GNP | float(10,2) | YES | | NULL || GNPOld | float(10,2) | YES | | NULL || LocalName | char(45) | NO | | || GovernmentForm | char(45) | NO | | || HeadOfState | char(60) | YES | | NULL || Capital | int(11) | YES | | NULL || Code2 | char(2) | NO | | |+----------------+---------------------------------------------------------------------------------------+------+-----+---------+--15 rows in set (0.01 sec)ERROR:No query specifiedmysql> explain select t.* from city t where t.countrycode in( select code from country);+----+-------------+---------+--------+---------------+---------+---------+---------------------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+---------+--------+---------------+---------+---------+---------------------+------+-------------+| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 4079 | NULL || 1 | SIMPLE | country | eq_ref | PRIMARY | PRIMARY | 3 | world.t.CountryCode | 1 | Using index |+----+-------------+---------+--------+---------------+---------+---------+---------------------+------+-------------+2 rows in set (0.04 sec)mysql> explain select t.* from city t join country t1 on t.countrycode = t1.code;+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+-------------+| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 4079 | NULL || 1 | SIMPLE | t1 | eq_ref | PRIMARY | PRIMARY | 3 | world.t.CountryCode | 1 | Using index |+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+-------------+2 rows in set (0.00 sec)
这样的优化可能返回重复的行,去重需要使用关键字distinct
4.Group by优化
正常执行情况下如下
mysql> explain select t.* from city t join country t1 on t.countrycode = t1.code group by t.id;+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+---------------------------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+---------------------------------+| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 4079 | Using temporary; Using filesort || 1 | SIMPLE | t1 | eq_ref | PRIMARY | PRIMARY | 3 | world.t.CountryCode | 1 | Using index |+----+-------------+-------+--------+---------------+---------+---------+---------------------+------+---------------------------------+2 rows in set (0.02 sec)
可以看到了使用临时表还有文件排序的方式来实现,那么我们应该怎么减少IO已经对资源的消耗呢,通过下面方式可以看出
mysql> explain select t.* from city t join (select code from country) t1 on t.countrycode = t1.code;+----+-------------+------------+-------+---------------+-------------+---------+---------------------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+------------+-------+---------------+-------------+---------+---------------------+------+-------------+| 1 | PRIMARY | t | ALL | NULL | NULL | NULL | NULL | 4079 | NULL || 1 | PRIMARY | <derived2> | ref | <auto_key0> | <auto_key0> | 3 | world.t.CountryCode | 10 | Using index || 2 | DERIVED | country | index | NULL | PRIMARY | 3 | NULL | 239 | Using index |+----+-------------+------------+-------+---------------+-------------+---------+---------------------+------+-------------+3 rows in set (0.00 sec)
这样就可以避免了文件排序还有使用该临时表的情况。
5.limit操作方式的优化
使用之前:
mysql> explain select * from city order by name limit 100,10;+----+-------------+-------+------+---------------+------+---------+------+------+----------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+------+----------------+| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4079 | Using filesort |+----+-------------+-------+------+---------------+------+---------+------+------+----------------+1 row in set (0.00 sec)
可以看到使用了文件排序,这样会造成性能上的低下。
优化方式:可以通过主键或者是含有索引的列进行order by 操作;
mysql> create index name_index on city(name);mysql> explain select name from city order by name limit 100,10;+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+| 1 | SIMPLE | city | index | NULL | name_index | 35 | NULL | 110 | Using index |+----+-------------+-------+-------+---------------+------------+---------+------+------+-------------+1 row in set (0.00 sec)
可以发现只扫描了35行而且使用了索引但是效率增加了很多。
MySQL之查询优化方式(笔记)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。