没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?
2018-12-24 林晓斌
在MySQL中,有很多看上去逻辑相同,但性能却差异巨大的SQL语句。对这些语句使用不当的
话,就会不经意间导致整个数据库的压力变大。
我今天挑选了三个这样的案例和你分享。希望再遇到相似的问题时,你可以做到举一反三、快速
解决问题。
案例一:条件字段函数操作案例一:条件字段函数操作
假设你现在维护了一个交易系统,其中交易记录表tradelog包含交易流水号(tradeid)、交易员
id(operator)、交易时间(t_modified)等字段。为了便于描述,我们先忽略其他字段。这个
表的建表语句如下:
假设,现在已经记录了从2016年初到2018年底的所有数据,运营部门有一个需求是,要统计发
生在所有年份中7月份的交易记录总数。这个逻辑看上去并不复杂,你的SQL语句可能会这么
写:
由于t_modified字段上有索引,于是你就很放心地在生产库中执行了这条语句,但却发现执行了
特别久,才返回了结果。
如果你问DBA同事为什么会出现这样的情况,他大概会告诉你:如果对字段做了函数计算,就
用不上索引了,这是MySQL的规定。
现在你已经学过了InnoDB的索引结构了,可以再追问一句为什么?为什么条件是where
t_modified='2018-7-1’的时候可以用上索引,而改成where month(t_modified)=7的时候就不行
了?
下面是这个t_modified索引的示意图。方框上面的数字就是month()函数对应的值。
mysql> CREATE TABLE `tradelog` (
`id` int(11) NOT NULL,
`tradeid` varchar(32) DEFAULT NULL,
`operator` int(11) DEFAULT NULL,
`t_modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tradeid` (`tradeid`),
KEY `t_modified` (`t_modified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
mysql> select count(*) from tradelog where month(t_modified)=7;
图1 t_modified索引示意图
如果你的SQL语句条件用的是where t_modified='2018-7-1’的话,引擎就会按照上面绿色箭头的
路线,快速定位到 t_modified='2018-7-1’需要的结果。
实际上,B+树提供的这个快速定位能力,来源于同一层兄弟节点的有序性。
但是,如果计算month()函数的话,你会看到传入7的时候,在树的第一层就不知道该怎么办了。
也就是说,对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃
走树搜索功能。走树搜索功能。
需要注意的是,优化器并不是要放弃使用这个索引。
在这个例子里,放弃了树搜索功能,优化器可以选择遍历主键索引,也可以选择遍历索引
t_modified,优化器对比索引大小后发现,索引t_modified更小,遍历这个索引比遍历主键索引
来得更快。因此最终还是会选择索引t_modified。
接下来,我们使用explain命令,查看一下这条SQL语句的执行结果。
剩余18页未读,继续阅读
lowsapkj
- 粉丝: 48
- 资源: 312
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0