由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里

前几天进行了一个数据库查询,比较缓慢,便查询了一下,在这里记录一下,方便以后翻阅,

1)先复习一下查询索引

(Tue Jun  :: ) db_1 >>show keys from xxxx; ==>(与show index from xxxx  是一样的)
+--------------+------------+-------------------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+-------------------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| xxxx | | PRIMARY | | iId | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_dPayTime | | dPayTime | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_sUserName | | sUserName | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_sPlatName | | iProxyId | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_sPlatName | | iServerId | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_sPlatName | | id | A | | NULL | NULL | YES | BTREE | | |
| xxxx | | index_dPayDate | | dPayDate | A | | NULL | NULL | | BTREE | | |
| xxxx | | Index_iPlatServerId_iPlayerId | | iPlatServerId | A | | NULL | NULL | | BTREE | | |
| xxxx | | Index_iPlatServerId_iPlayerId | | iPlayerId | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_dPayDate_yue_iProxyId | | dPayDate_yue | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_dPayDate_yue_iProxyId | | iProxyId | A | | NULL | NULL | | BTREE | | |
| xxxx | | index_dPayDate_yue_iProxyId | | iPayType | A | | NULL | NULL | YES | BTREE | | |

类型介绍:

1、Table 表的名称。
2、 Non_unique 如果索引不能包括重复词,则为0,如果可以则为1。
3、 Key_name 索引的名称
4、 Seq_in_index 索引中的列序列号,从1开始。
5、 Column_name 列名称。
6、 Collation 列以什么方式存储在索引中。在mysql中,有值‘A’(升序)或NULL(无分类)。
7、Cardinality 索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。
8、Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。
9、 Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。
10、 Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。
11、 Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
12、 Comment 索引注释

我们要注意:

 cardinality 的值越大,那么命中此索引的几率越高
我们可以强制进行命中哪个索引
Cardinality是一个预估值,而不是一个准确值,基本上用户也不可能得到一个准确的值,在实际应用中,Cardinality/n_row_in_table应尽可能的接近1,
如果非常小,那用户需要考虑是否还有必要创建这个索引。故在访问高选择性属性的字段并从表中取出很少一部分数据时,对于字段添加B+树索引是非常有必要的

如果要查看Cardinality更为详细的信息,可以在:http://www.cnblogs.com/olinux/p/5140615.html 中查看

2 ) 同事在线上进行了一次查询操作:

select * from t_xxxx where pay_id in (
select pay_id from t_xxxx where dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31" group by pay_id having count(pay_id) > )
  and dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31"

然后执行半天都出不来结果,问我这边怎么了,我看了一下:

explain select * from t_xxxx where pay_id in (
select pay_id from t_xxxx where dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31" group by pay_id having count(pay_id) > )

得到结果:

| id | select_type        | table        | type  | possible_keys  | key            | key_len | ref  | rows    | Extra                                        |
+----+--------------------+--------------+-------+----------------+----------------+---------+------+---------+----------------------------------------------+
| | PRIMARY | t_xxxx | ALL | NULL | NULL | NULL | NULL | | Using where |
| | DEPENDENT SUBQUERY | t_xxx | range | index_dPayTime | index_dPayTime | | NULL | | Using where; Using temporary; Using filesort |

这条sql包含了子查询和父查询,如果我们先查子查询,可以看到执行非常快:

select pay_id from t_xxxx where dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31" group by pay_id having count(pay_id) > ;
Empty set (0.42 sec)
0.42秒执行完毕

explain可以看到:

+----+-------------+--------------+-------+----------------+----------------+---------+------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+----------------+----------------+---------+------+--------+----------------------------------------------+
| | SIMPLE | t_xxxx | range | index_dPayTime | index_dPayTime | | NULL | | Using where; Using temporary; Using filesort |
+----+-------------+--------------+-------+----------------+----------------+---------+------+--------+----------------------------------------------+

然后我们再尝试父查询查询,替换一下子查询,直接给出子查询的结果:

select * from t_xxxx where pay_id in (
-> '','','');
3 rows in set (0.50 sec)
0.56 秒查询完毕

那么两者结合起来,岂不是只需要1秒钟就可以结束查询。

然而真实情况并非如此,这不是简单的1+1,而是乘法,如果用in去操作,子查询影响的行数是多少条,就会乘以父查询影响的行数。这样的乘积量是非常大的,所以查询非常的久。

因此这里推荐改成联表==>

select * from t_xxxx tpp1, (select pay_id from t_xxxx where dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31" group by pay_id 
having count(pay_id) > ) tpp2
where tpp1.pay_id=tpp2.pay_id and dPayTime>="2017-06-21 12:12:31" AND dPayTime<="2017-06-28 12:12:31"

如果是联表,那么就会控制两者计算好后,才开始进行联表。而其中子查询的结果是很少的,只有几条,联表起来因此计算很快,2秒完成

这里我们也要注意,如果查询的时间跨度很大,条数很大,那么索引就不会被命中,会自动采用普通查询。

explain select * from t_xxxx tpp1, (select pay_id from t_xxxx where dPayTime>="2017-06-01 12:12:31" AND dPayTime<="2017-06-28 12:12:31" group by pay_id having 
count(pay_id) > ) tpp2 where tpp1.pay_id=tpp2.pay_id and dPayTime>="2017-06-01 12:12:31" AND dPayTime<="2017-06-28 12:12:31"
+----+-------------+--------------+--------+----------------+------+---------+------+---------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+----------------+------+---------+------+---------+----------------------------------------------+
| | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | | |
| | PRIMARY | tpp1 | ALL | index_dPayTime | NULL | NULL | NULL | | Using where |
| | DERIVED | t_xxxx | ALL | index_dPayTime | NULL | NULL | NULL | | Using where; Using temporary; Using filesort |
+----+-------------+--------------+--------+----------------+------+---------+------+---------+----------------------------------------------+
并没有命中索引

那么我们就要尽量的去优化它,没有命中索引下查询起来是比较慢的。

一次mysql调优过程的更多相关文章

  1. MySQL 调优/优化的 100 个建议

    MySQL 调优/优化的 100 个建议   MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供 101 条优化 MySQL 的建议.有些技巧适合特定 ...

  2. MySQL调优系列基础篇

    前言 有一段时间没有写博客了,整天都在忙,上班,录制课程,恰巧最近一段时间比较清闲,打算弄弄MYSQL数据库. 关于MySQL数据库,这里就不做过多的介绍,开源.免费等特性深受各个互联网行业喜爱,尤其 ...

  3. mysql调优 基础

    MySQL调优可以从几个方面来做: 1. 架构层:做从库,实现读写分离: 2.系统层次:增加内存:给磁盘做raid0或者raid5以增加磁盘的读写速度:可以重新挂载磁盘,并加上noatime参数,这样 ...

  4. MySQL调优三步曲(慢查询、explain profile)

    在做性能测试中经常会遇到一些sql的问题,其实做性能测试这几年遇到问题最多还是数据库这块,要么就是IO高要么就是cpu高,所以对数据的优化在性能测试过程中占据着很重要的地方,下面我就介绍一些msyql ...

  5. MySQL(调优慢查询、explain profile) 转

    转自http://www.linuxidc.com/Linux/2012-09/70459.htm mysql profile explain slow_query_log分析优化查询 在做性能测试中 ...

  6. 数据库MySQL调优实战经验总结<转>

    数据库MySQL调优实战经验总结 MySQL 数据库的使用是非常的广泛,稳定性和安全性也非常好,经历了无数大小公司的验证.仅能够安装使用是远远不够的,MySQL 在使用中需要进行不断的调整参数或优化设 ...

  7. MySQL 调优基础(一) CPU与进程

    一般而言,MySQL 的调优可以分为两个层面,一个是在MySQL层面上进行的调优,比如SQL改写,索引的添加,MySQL各种参数的配置:另一个层面是从操作系统的层面和硬件的层面来进行调优.操作系统的层 ...

  8. 记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?)

    记一次数据库调优过程(IIS发过来SQLSERVER 的FETCH API_CURSOR语句是神马?) 前几天帮客户优化一个数据库,那个数据库的大小是6G 这麽小的数据库按道理不会有太大的性能问题的, ...

  9. mysql调优最大连接数

    一.mysql调优 1.1 报错: Mysql: error 1040: Too many connections 1.2 原因: 1.访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务器 ...

随机推荐

  1. 「小程序JAVA实战」小程序的留言和评价功能(70)

    转自:https://idig8.com/2018/10/28/xiaochengxujavashizhanxiaochengxudeliuyanhepingjiagongneng69/ 目前小程序这 ...

  2. JSF + Primefaces: Problem with “rendered” components with ajax

    Cant seem to get rendered to work correctly with update attributes. Here is my codes <ui:define n ...

  3. 1 数据库开发--MySQL介绍

    1.数据库管理软件 C/S 并发.锁 :SQL语句.语法 基本管理和语法学习 一.介绍: mysql数据库管理软件: 套接字:服务端,客户端:客户端可访问服务端得数据 1.支持并发:操作得是共享得数据 ...

  4. javascript 对象的扩展性

    javascript 对象 的可扩展性 javascript 对象中的可扩展性指的是:是否可以给对象添加新属性.所有的内置对象和自定义对象显示的都是可扩展的,对于宿主对象,则有javascript 引 ...

  5. pac (PAC(Proxy Auto Config) 是一个 Script;经由编写这个 Script,我们可以让系统判断在怎么样的情形下,要利用哪一台 Proxy 来进行联机。)

    PAC自动代理文件格式,教你如何写PAC文件 PAC文件格式 PAC文件是纯文本格式的,实际上就是JavaScript文件.Chrome/Chromium的扩展Switchy!的"Auto ...

  6. js常用代码整理

    引用js <script type="text/javascript" src="js/jquery-1.11.2.min.js"></scr ...

  7. eclipse里启动tomcat无法通过127.0.0.1访问

    在eclipse里面添加tomcat,再发布一个web项目进去,然后启动tomcat,日志显示tomcat在eclipse里面正常启动,hosts里面配置了ip跟域名的对应关系. 通过域名访问可以正常 ...

  8. Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics

    UIKit 视图树模型 1.视图树模型 计算机图形实际上是一个视图树模型,每个视图都有一个本地坐标系.每个本地坐标系的组成部分是:原点在父坐标系中的位置,每个基在父坐标系中的位置,由此就可以根据向量的 ...

  9. Qt Thread

    Threading Classes (Qt help manual key words) These Qt Core classes provide threading support to appl ...

  10. Linux gperf命令

    一.简介 GNU 的 gperf 工具是一种 "完美的" 散列函数,可以为用户提供的一组特定字符串生成散列表.散列函数和查找函数的 C/C++ 代码.通过本文学习如何使用 gper ...