MySQL实践2
2024-12-8
| 2025-2-16
0  |  Read Time 0 min
type
status
date
slug
summary
tags
category
icon
password
 

sql逻辑相同,性能差别大?

 

条件字段函数操作

 
比如说
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;
 
去查询所有年份7月的交易记录总数
 
mysql> select count(*) from tradelog where month(t_modified)=7;
如果写这个就特别慢。即使有索引。
为什么?:对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。
notion image
应该要改成这样:
mysql> select count(*) from tradelog where -> (t_modified >= '2016-7-1' and t_modified<'2016-8-1') or -> (t_modified >= '2017-7-1' and t_modified<'2017-8-1') or -> (t_modified >= '2018-7-1' and t_modified<'2018-8-1');
 
类似于:
  • 原来的索引:图书按出版日期排序
  • 使用函数后:突然要按"出版日期的月份"查找
  • 数据库不得不翻看每一本书
 
 

类型转换

 
比如经常遇到的:
mysql> select * from tradelog where tradeid=110717;
 
这条语句需要走全表扫描。因为tradeid 的字段类型是 varchar(32),而输入的参数却是整型,所以需要做类型转换。
 
在 MySQL 中,字符串和数字做比较的话,是将字符串转换成数字。
 
notion image
相当于每个都要将id转为数字,和这个where进行比较,全表了
 
 

查一行速度也很慢

 
 

第一类查询时间长不返回

 
比如mysql> select * from t where id=1;
 
简单一句sql,不返回,大概率是表被锁住了。可以用show processlist来查看
 
notion image
 
基本就是类似于a要写,b要读锁—》写锁是排他锁,意味着其他会话不能读取或修改这张表
notion image
 
这类问题的处理方式,就是找到谁持有 MDL 写锁,然后把它 kill 掉
 
用这个可以查询加表锁的线程id
notion image
 
  • 开发
  • 极客公园2025MySQL实践
    Loading...
    Catalog