mysql之查询优化探索
今天遇到一个实际的mysql查询性能问题,试验了半天,终于摸出点门道,业务背景如下:
有如下数据库表
CREATE TABLE `tb_feature` (
`id` int(11) NOT NULL,
`feature_desc` char(255) NOT NULL,
`type_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_featuretype` (`type_id`),
KEY `feature_desc` (`feature_desc`),
CONSTRAINT `fk_featuretype` FOREIGN KEY (`type_id`) REFERENCES `tb_feature_type` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
其中 type_id 是另一张表的外键。
表中有数据1846058条,数据示例如下:
| 2015041889 | tgw__busi__zy__业务(蜀山传奇)__appid(1)__abc | 22 |
| 2015046243 | tgw__busi__zy__业务(侠义无双)__appid(2)__abc | 22 |
| 2015048614 | tgw__busi__zy__业务(大笑西游)__appid(3)__abc | 22 |
| 2015052785 | tgw__busi__zy__业务(幻世仙征)__appid(6)__abc | 22 |
| 2015079514 | tgw__busi__zy__业务(海岛大亨)__appid(7)__abc | 22 |
| 2015086117 | tgw__busi__zy__业务(千智风声)__appid(9)__def | 23 |
| 2015087409 | tgw__busi__zy__业务(红色火线)__appid(10)__def | 23 |
| 2015096361 | tgw__busi__zy__业务(寻侠)__appid(11)__def | 23 |
| 2015096613 | tgw__busi__zy__业务(JayLi25428)__appid(13)__def | 23 |
| 2015100282 | tgw__busi__zy__业务(北欧传说)__appid(15)__def | 23 |
其中feature_desc组成如下: tgw__busi__zy__业务($appname)__appid($业务id)_$type
mysql> select count(*) from tb_feature;
+----------+
| count(*) |
+----------+
| 1846058 |
+----------+
查询需求场景:
type_id=22 ,且 appid固定为某一批特定值,appname未知, type=abc;
type_id=23 ,且 appid固定为某一批特定值,appname未知, type=def;
由于appname 未知,只能使用like查询,固有如下语句:
select id as ft_id, feature_desc as ft_desc from tb_feature where type_id IN (22,23) and feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__def' or feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__abc';
查询结果为1条数据,但是耗时 (4.04 sec)接着测试更多的批量查询, like后面跟10个匹配条件,耗时 15.23秒。
对于一个实际的业务需求来讲,这个查询速度显然不能满足需要。
使用explain 语句来跟踪这条语句:
+----+-------------+----------------+------+-----------------------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+-----------------------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | tb_feature | ALL | fk_featuretype,feature_desc | NULL | NULL | NULL | 1918565 | Using where |
参考百度文库explain的解释:Mysql Explain 语法详细解析
可以看出2点:
1. 没有使用索引查询,全亮数据匹配;
2.1918565 大于表总数据量。
按照设想,先根据type_id过滤一次,总数据约4261条,然后从这4261条数据中使用like匹配查询,应该是不至于需要4秒的。
将sql语句修改一下,仅仅加入一个(),
select id as ft_id, feature_desc as ft_desc from tb_feature where type_id IN (22,23) and (feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__def' or feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__abc');
查询耗时0..01秒,继续explain,看看其中的区别:
+----+-------------+----------------+-------+-----------------------------+----------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+-------+-----------------------------+----------------+---------+------+------+-------------+
| 1 | SIMPLE | tb_feature | range | fk_featuretype,feature_desc | fk_featuretype | 4 | NULL | 4261 | Using where |
+----+-------------+----------------+-------+-----------------------------+----------------+---------+------+------+-------------+
rows显示仅有4261行数据需要进一步使用where条件查询,说明这一次type_id起了作用,那是否意味着使用了fk_featuretype 索引呢,。
接下来继续修改查询语句:
select id as ft_id, feature_desc as ft_desc from tb_feature where type_id IN (22,23) and (feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__def') or (feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__abc');
查询耗时4.04秒
select id as ft_id, feature_desc as ft_desc from tb_feature where (type_id IN (22,23)) and ((feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__def') or (feature_desc like 'tgw__busi__zy__业务(%)__appid(1)__abc'));
查询耗时0.01秒
对于like后面跟10个匹配条件的查询,用()括起来之后耗时也仅为0.26秒。
可见,将 后面的 feature_desc like 用()整体括起来,索引方能起作用。
为什么会有如此大的区别呢?条件的顺序或者一个() 到底改变了什么?
mysql之查询优化探索相关推荐
- psql where里有自定义函数慢_阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结...
MySQL优化概述 MySQL数据库常见的两个瓶颈是:CPU和I/O的瓶颈. CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候. 磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应 ...
- MySQL 慢查询优化
为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...
- mysql数据库查询优化建议_mysql数据库查询优化的24条建议
MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供一些关于Mysql 数据库查询优化的24条优化建议,仅供参考. Mysql 查询优化 1.使用慢查询 ...
- php mysql查询例子_php mysql一个查询优化的简单例子
PHP+Mysql是一个最经常使用的黄金搭档,它们俩配合使用,能够发挥出最佳性能,当然,如果配合Apache使用,就更加Perfect了. 因此,需要做好对mysql的查询优化,下面通过一个简单的例子 ...
- 【MySQL】查询优化
[MySQL]查询优化 1. 优化目的与目标 1.1 为什么要进行查询优化 1.1 MySQL优化目标 2. 优化流程及思路 2.1 调优时你需要关注哪些指标 2.1 合理监控 2.3 MySQL优化 ...
- MySQL 的查询优化
说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型-- 你是否真的理解这些优化技巧?是否理解其背后的工 ...
- 阿里P7架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结
MySQL优化概述 MySQL数据库常见的两个瓶颈是:CPU和I/O的瓶颈. CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候. 磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应 ...
- mysql 子查询优化一例
2019独角兽企业重金招聘Python工程师标准>>> 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化 ...
- mysql 测试快生产慢_生产上MySQL慢查询优化实战,SQL优化实战
之前看了饿了么团队写的一篇博客:等等!这两个 Spring-RabbitMQ 的坑我们已经替你踩了.深受启发,一定要取个能吸引读者眼球的标题,当然除了响当当的标题以外,内容也要是干货.为什么会想取这样 ...
最新文章
- 如何ping通服务器的公网IP?
- 计算机科学创新大赛,计信学院举办第六届科技创新小发明大赛
- Dubbo+Zookeeper 基础讲解
- spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
- Kettle组件Spoon的使用
- ROM 、RAM和FLASH 的区别
- C语言基础进阶之 MessageBox()用法简介
- 科罗拉多大学波尔得分校计算机科学,科罗拉多大学波尔得分校专业
- 数学基础篇 有理数(一)
- vue打开新html,vue在新窗口打开页面的方法
- android webview 劫持,微信webview 及第三方浏览器劫持视频问题
- 信创终端之Linux桌面系统:原生桌面 vs 定制魔改
- CSS选择器的优先级的相关介绍
- 【LeetCode刷题笔记-39 714.买卖股票的最佳时机(含手续费)】
- IP地址和域名之间的转换
- 微软发布命令行神器,文件误删秒恢复
- Arcgis正方形缓冲工具
- Oracle性能调优之/*+parallel(t,8)*/
- 关于笔记本检测不到外接显示器的问题
- [小说]魔王冢(16)寻凶(二)
热门文章
- ENVI对LandSat8 (OLI)图像 FLAASH大气校正 input radiance image data 报错 no valid data encountered in this file
- 基于Module Federation的模块化跨栈方案探索
- Ios精品源码,tableview下载视频直播源播放器图片位置3D立体旋转相册屏风动画...
- 白话Layer2.Finance:DeFi这座城的公共地铁
- Vue.js入门教程(适合初学者)
- 跨国面板数据(1960-2020)一:农业(农机+耕地+产量+面积+生产指数)(stata版)
- ReadProcessMemory与WriteProcessMemory用例分析
- 科学计算机 app,万能科学计算器
- kali linux 软件管理_白帽子***与网络安全工程师教你:Kali Linux和Windows软件管理的异同【二】...
- java 命名管道_linux 命名管道实例详解