加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

影响MySQL查询性能的案例

发布时间:2019-05-17 19:58:44 所属栏目:编程 来源:风度玉门
导读:在互联网应用中,凡是环境下我们查询DB 只会行使简朴的、查询服从较高的SQL,大部门的逻辑都必要在代码中去实现。本日先容一下,一些看起来简朴的SQL,也有也许导致查询机能的低下。 WHERE前提字段行使函数 假设我们有如下建设表的语句 mysqlCREATETABLE`t
副问题[/!--empirenews.page--]

 

影响MySQL查询机能的案例

在互联网应用中,凡是环境下我们查询DB 只会行使简朴的、查询服从较高的SQL,大部门的逻辑都必要在代码中去实现。本日先容一下,一些看起来简朴的SQL,也有也许导致查询机能的低下。

WHERE前提字段行使函数

假设我们有如下建设表的语句

  1. mysql> CREATE TABLE `tradelog` ( 
  2.  `id` int(11) NOT NULL, 
  3.  `tradeid` varchar(32) DEFAULT NULL, 
  4.  `operator` int(11) DEFAULT NULL, 
  5.  `t_modified` datetime DEFAULT NULL, 
  6.  PRIMARY KEY (`id`), 
  7.  KEY `tradeid` (`tradeid`), 
  8.  KEY `t_modified` (`t_modified`) 
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

上面是一种时刻维度的营业表,此时假如我们要仅仅查询全部数据中 7月份的买卖营业笔数。此时我们也许会想到如下SQL

  1. mysql> select count(*) from tradelog where month(t_modified)=7; 

从上面的建表语句我们可以看出,索引是建在 t_modified 上面的。此时假如我们要查询上面的SQL 查询,执行进程将会是如下:

影响MySQL查询机能的案例

从上图可以看出,当对索引字段做函数操纵后,也许会造成索引布局次序的错杂。因此,MySQL 会放弃走搜刮树的查询布局,取而代之的是全索引扫描。(优化器选择走 t_modified 索引全表遍历,而不选择 主键索引的缘故起因是 t_modified 索引相对小一点)

凡是环境下,我们必要人工的去优化SQL 。虽然这每每必要团结详细的营业数据行止理赏罚了,如上面的查询也许会优化为如下的环境:

  1. select count(*) from tradelog where (t_modified >= '2016-7-1' and t_modified < '2016-8-1') or 
  2. (t_modified >= '2017-7-1' and t_modified < '2017-8-1') or  
  3. (t_modified >= '2018-7-1' and t_modified < '2018-8-1'); 

对付MySQL 的简朴查询来说,尚有一个坑就是:

  1. SELECT * FROM tradelog WHERE id + 1 = 999;  

这个时辰,MySQL 也不会主动的去做 “移项”的优化,此时也会造玉成表扫描。

字段隐式转换

MySQL 中的字段隐式转换也许会引起索引不行用,下面我们先看一个字符与数字较量的例子。如下所示:

  1. mysql> select '10' > 9; 

当我们执行上面的SQL 时,会获得如下功效

影响MySQL查询机能的案例

从执行功效可以看出,字符范例默认会转换为数字范例。必要留意的点是:'10' ->10、'10A' -> 10、可是 'A10' -> 0 ,转换会过滤掉无效字符,可是必要数字开头,不然就转化为 0 。

此刻我们看一下如下语句:

  1. mysql> explain select * from tradelog where tradeid = 222; 

影响MySQL查询机能的案例

由于 tradeid 是 VARCHAR 范例,MySQL 会将其转化为 数字然后较量,最终导致索引不行用,全表扫描。当我们对 int 范例字段查询时,对应的value 值可以随意行使 10 可能 '10' ,此时城市转化为 数字 10 ,行使索引。上面的语句执行就相等于如下:

  1. mysql> explain select * from tradelog where CAST(tradeid AS signed int) = 222; 

也就是潜匿的在查询字段上面行使了函数操纵,从而导致了全表扫描。

隐式字符编码转换

上面的案例先容了,差异范例字段之间的范例转换。对付沟通范例(VARCHAR) 的差异字符集编码也也许会呈现隐式转换。下面再建设一张日记详情表(trade_detail),然后在写入一些数据,如下所示:

  1. mysql> CREATE TABLE `trade_detail` ( 
  2.  `id` int(11) NOT NULL, 
  3.  `tradeid` varchar(32) DEFAULT NULL, 
  4.  `trade_step` int(11) DEFAULT NULL, /* 操纵步调 */ 
  5.  `step_info` varchar(32) DEFAULT NULL, /* 步调信息 */ 
  6.  PRIMARY KEY (`id`), 
  7.  KEY `tradeid` (`tradeid`) 
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
  9. insert into tradelog values(1, 'aaaaaaaa', 1000, now()); 
  10. insert into tradelog values(2, 'aaaaaaab', 1000, now()); 
  11. insert into tradelog values(3, 'aaaaaaac', 1000, now()); 
  12. insert into trade_detail values(1, 'aaaaaaaa', 1, 'add'); 
  13. insert into trade_detail values(2, 'aaaaaaaa', 2, 'update'); 
  14. insert into trade_detail values(3, 'aaaaaaaa', 3, 'commit'); 
  15. insert into trade_detail values(4, 'aaaaaaab', 1, 'add'); 
  16. insert into trade_detail values(5, 'aaaaaaab', 2, 'update'); 
  17. insert into trade_detail values(6, 'aaaaaaab', 3, 'update again'); 
  18. insert into trade_detail values(7, 'aaaaaaab', 4, 'commit'); 
  19. insert into trade_detail values(8, 'aaaaaaac', 1, 'add'); 
  20. insert into trade_detail values(9, 'aaaaaaac', 2, 'update'); 
  21. insert into trade_detail values(10, 'aaaaaaac', 3, 'update again'); 
  22. insert into trade_detail values(11, 'aaaaaaac', 4, 'commit'); 

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读