前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL中两个小的优化案例

MySQL中两个小的优化案例

作者头像
AsiaYe
发布2019-11-06 17:17:55
4680
发布2019-11-06 17:17:55
举报
文章被收录于专栏:DBA随笔

MySQL中两个小的优化案例

今天介绍两个优化案例,一个是关于min和max这种函数的,另外一个是关于count这个计数函数的。

先来看看第一种情况,关于min和max的:

代码语言:javascript
复制
select min(id) from test_1 where name='yeyz';

上面的SQL中,name列是没有索引的,而id列是主键,但是where条件中写的是name列,所以MySQL会走一次全表扫描,这我们从执行计划中也可以看出来,

代码语言:javascript
复制
mysql:yeyztest 23:25:30>>explain select min(id) from test_1 where name='yeyz';
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test_1 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   43 |    10.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

对于这个SQL,其实可以做的优化是强行制定使用某个索引去实现,例如我们可以改为:

代码语言:javascript
复制
select id from test_1 use index(primary) where name='yeyz' limit 1;

如果SQL中使用的是max函数,则可以讲id进行倒序排列,然后取第一条即可。

关于count()函数

关于这个函数,首先要说明的一点是,这个函数是不统计值为null的列的,如果你想用count(字段名)的方式来统计行数,那么需要保证count的字段是非空的,否则结果可能有问题。

我们知道,count(*)的写法会扫描全表,在Innodb和MyIsam中对这个函数的处理不同,MyIsam中可以非常快的得到这个结果,而不用扫描整个表。在MyIsam的存储引擎下,例如我们想要统计一个100w数据记录的表中id>5的值,正常情况下,我们几乎要扫描全部的记录,基于MyIsam的特性,我们可以这样写来实现对它的优化:

代码语言:javascript
复制
mysql:yeyztest 23:34:45>>explain select count(*) from test_1 where id>5;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test_1 | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |   38 |   100.00 | Using where; Using index |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

mysql:yeyztest 23:34:57>>explain select (select count(*) from test_1)-count(*) from test_1 where id<5;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------+
| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                        |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------+
|  1 | PRIMARY     | test_1 | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |    4 |   100.00 | Using where; Using index     |
|  2 | SUBQUERY    | NULL   | NULL       | NULL  | NULL          | NULL    | NULL    | NULL | NULL |     NULL | Select tables optimized away |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+------------------------------+
2 rows in set, 1 warning (0.00 sec)

使用反向搜索的思路,可以让记录的行数表的很小。这个例子中,test_1表中有43条记录。反向搜索之后,原来需要过滤38条记录,一下子变成了4条记录,这个提升已经很明显了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档