首页 技术 正文
技术 2022年11月12日
0 收藏 964 点赞 4,197 浏览 3029 个字

语句是这条

SELECT DISTINCT bank, account FROM sdb_payments WHERE status=”succ”;

status 上有索引,但不是主索引。

status 字段 `status` enum(‘succ’,’failed’,’cancel’,’error’,’progress’,’invalid’,’timeout’,’ready’) NOT NULL DEFAULT ‘ready’

我本来以为这是 一条很普通的语句,但是平均执行时间达到了接近3s 。数据量是25w ,

接着是explain

1 | SIMPLE      | sdb_payments | ref  | status        | status | 1       | const | 123886 | Using where; Using temporary

using temporary 这个就很让人疑惑了。distinct 居然要用临时文件,在我的理解,using filesort 和using temporary 都是比较慢的操作,因为设计磁盘的io会很多。

接着是profile 详细支出。

set profiling =1;

SELECT distinct  bank, account FROM sdb_payments WHERE status=”succ”;

show profiles;
+———-+————+———————————————————————-+
| Query_ID | Duration | Query |
+———-+————+———————————————————————-+
| 1 | 1.20948900 | SELECT distinct bank, account FROM sdb_payments WHERE status=”succ” |
+———-+————+———————————————————————-+

show proflie for query 1;

+——————————–+———-+
| Status | Duration |
+——————————–+———-+
| starting | 0.000060 |
| checking query cache for query | 0.000071 |
| Opening tables | 0.000021 |
| System lock | 0.000008 |
| Table lock | 0.000034 |
| init | 0.000140 |
| optimizing | 0.000019 |
| statistics | 0.000088 |
| preparing | 0.000030 |
| Creating tmp table | 0.000040 |
| executing | 0.000009 |
| Copying to tmp table | 2.512772 |
| Sending data | 0.000056 |
| end | 0.000007 |
| removing tmp table | 0.000017 |
| end | 0.000008 |
| query end | 0.000007 |
| freeing items | 0.000027 |
| storing result in query cache | 0.000275 |
| logging slow query | 0.000014 |
| logging slow query | 0.000065 |
| cleaning up | 0.000009 |
+——————————–+———-+

为啥会有tmp table 呢,看文档。

In most cases, a DISTINCT clause can be considered as a special case of GROUP BY. For example, the following two queries are equivalent:

SELECT DISTINCT c1, c2, c3 FROM t1
WHERE c1 > const;SELECT c1, c2, c3 FROM t1
WHERE c1 > const GROUP BY c1, c2, c3;

大多数情况下,distinct 都会转化为group by 的语句,

所以再看group by的优化:

The most general way to satisfy a GROUP BY clause is to scan the whole table and create a new temporary table where all rows from each group are consecutive, and then use this temporary table to discover groups and apply aggregate functions (if any). In some cases, MySQL is able to do much better than that and to avoid creation of temporary tables by using index access.

通常情况下,group by会扫描整个表,然后创建一个临时表。。 这里不是很明白。在某些情况下,mysql能用所以而避免用临时表。

SELECT distinct bank, account FROM sdb_payments WHERE status=”succ” 这句sql 我觉得是被优化器转化为

SELECT bank, account FROM sdb_payments WHERE status=”succ” group by bank,account

这里我添加( bank,account)的联合索引,发现还是没有走索引。。

难道是我想错了?

于是再次explain ,这次加上extended ,然后 马上show warnings ,可以看到解析器是怎么解析sql 的。

Note  | 1003 | select distinct `test`.`sdb_payments`.`bank` AS `bank`,`test`.`sdb_payments`.`account` AS `account` from `test`.`sdb_payments` where (`test`.`sdb_payments`.`status` = ‘succ’ )

想了想,应该把status 也加到索引里面去,变成(status,bank,accout),然后发现

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————–+——+—————-+———+———+——-+——–+———-+————————–+
| 1 | SIMPLE | sdb_payments | ref | status,idx_acc | idx_acc | 1 | const | 123917 | 100.00 | Using where; Using index |

速度极快。

上一篇: percona 5.6的安装
下一篇: RBAC权限分配
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,031
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,862