SQL调优笔记

1. SQL性能下降原因

开始由于数据较少,SQL的执行效率不会有太大影响,但当业务数据增多时,SQL的性能会逐渐下降。SQL性能下降主要有以下4种原因

  • SQL语言写的差【引起全表搜索,创建临时表等】导致SQL性能下降
  • 索引失效
  • 查询语句关联了太多JOIN
  • 服务器参数设置存在问题【缓冲区等】

2. SQL调优

SQL调优主要分为4个步骤:

  • 慢查询语句的捕获
  • 使用explain分析低效语句
  • show profile分析低效语句
  • SQL数据库服务器的调优

2.1 慢查询的开启和捕获

2.1.1 查看日志开启情况

进入mysql后,可以使用show variables like '%low_query_log%'来查看慢查询日志开启情况,结果会返回slow_query_log的开启情况,一般是off,还有slow_query_log所在的位置

mysql -u root -p    # 今天mysql
# Enter password
show variables like '%slow_query_log%';

2.1.2 开启日志

输入set global slow_query_log = 1;开启慢查询日志
注意在调式时才打开慢查询日志,平时不需要打开

set global slow_query_log = 1;  # 开启慢查询日志

set global slow_query_log = 0;  # 关闭慢查询日志

2.1.3 查看和设置阈值

多慢的sql语句才会被记录在慢查询日志中呢?这时候就需要调整阈值,使用show variables like '%long_query_time%';可以查看当前的阈值,一般默认是10s

如果需要更小或者更大的阈值,可以使用set global long_query_time = ;来设定理想的阈值,根据实际情况设定对应阈值

show variables like '%long_query_time%';

set global long_query_time = 3;  # 设定阈值为3秒

2.1.4 查看低效SQL

在mysql中输入 show global status like'%slow_queries%'来查看低于阈值的sql语句条数,然后根据查询慢日志是否开启返回的结果slow_query_log可以查看慢查询日志文件所在位置,打开慢查询日志查看慢于阈值的低效SQL语句

 show global status like'%slow_queries%'

慢查询日志主要是用于低效SQL语句的捕获,捕获了对应的低效SQL语句后,就可以对其进行分析


2.2 使用explain分析

对于慢查询日志捕获的低效SQL语句,可以使用explain进行分析,分析其低效的原因
explain + SQL语句 可以查看单个SQL语句的执行计划,模拟优化器执行SQL语句,从而知道MYSQL是如何处理MYSQL语句的,进而分析查询语句或表结构的性能瓶颈

使用explian + SQL语句后会出现如图所示表格,各参数意义如下:

  • id:一组数字,表示查询中执行select子句或操作表的顺序
    - d相同时,执行顺序由上至下
    - d不同,id值越高,越先执行
  • select_type:查询类型
    - SIMPLE:代表类型是简单查询
    - PRIMARYKEY:代表主查询
    - UNION:UNION查询
    - UNION:UNION返回的结果
    - SUBQUERY:子查询
  • type:访问类型
    - ALL:全表扫描
    -** const**:代表常量
    - eq_ref:唯一性索引扫描,只记录一条记录与之匹配
    - ref:代表非唯一性索引扫描,返回匹配某个单独值得所有行
    - range:只检索给定范围得行,使用一个索引来选择行
    - system:表中仅有一行

type类型从优到差的顺序为system > const > eq_ref > ref > range > index > ALL
要尽量避免出现ALL,因为全表扫描严重影响SQL性能

  • possible_key:显示可能应用在表中的索引,一个或多个【但不一定被查询使用】

  • key:实际使用的索引【如果为NULL,要么没有建立,要么索引失效】

  • key_len:表示索引中使用的字节数【同样查询结果得情况下,key_len越小越好】

  • ref:显示索引的哪一列被实际使用了

  • row:根据表统计信息及索引选用情况,大致估算出找到所需得记录所需读取的行数【越少越好】

  • Extra:包含不适合在其他列中显示但十分重要得额外信息
    - using filesort:文件内排序【尽量不要有using filesort】
    - using temporary:新建内部得临时表【尽量不要生成临时表常见于order by 和 group by】
    - using index:表明相应得select操作中使用了覆盖索引,避免访问了表得数据行【尽量有using index】
    - using join buffer :使用了连接缓存
    - impossible where:where子句得值总是False,不能用来获取任何元组
    - distinct

实际使用时,主要考察,id;type;key;row;Extra。考察type中是否有ALL;key是否存在索引失效;extra是否存在using filesort和using temporary这些严重影响性能的情况


2.3 使用show profile分析

对比explain,使用show profile可以更进一步分析低效的SQL 语句

show profile 提供可以用来分析当前会话中语句执行的资源消耗情况,用于SQL的调优测量,默认情况下,参数处于关闭状态

2.3.1 开启profile

使用SHOW VARIABLES LIKE 'profiling';查看profiling开启状态,默认关闭,保存15条运行结果

使用SET PROFILING=on; 开启profiling

SHOW VARIABLES LIKE 'profiling';  # 查看profiling开启状态

SET PROFILING=on;                  # 开启profiling

2.3.2 分析prifile

开启profile后,SQL语句会被记录在profiles中,使用show profiles; 可以查看语句对应的id和运行时间

一般查看cpu占用和io情况,可以使用show profile cpu ,block io for query <id>;来查看对应id语句的cpu和io情况,也可以改为ALL查看全部信息

show profiles     # 查看profiles

show profile cpu ,block io for query 3;  # 3可以改为其他id值

2.3.3. 相关结果说明

converting HEAP to MYISAM      #查询结果太大,内存不够用了往磁盘上搬了
Creating tmp table             #创建临时表
Copying to tmp table on disk ; #把内存中临时表复制到硬盘

2.4 SQL数据库服务器的调优

增大buffer缓冲区等方法进行数据库服务器调优


2.5 索引分析

2.5.1 索引基本概念

  • 索引的概念:索引是帮助MYSQL高效获取数据得数据结构,可以简单理解为排好序得,帮助快速查找得数据结构

  • 索引优势

    • 提高数据检索效率,降低io成本
    • 降低数据排序的成本,降低cpu的损耗
  • 索引劣势

    • 索引实际上是一张表,也是要占用空间
    • 会降低表的更新速度【因为要同时更新索引】
  • MYSQL索引基本语法

CREATE INDEX [indexName] ON 表明(列名)  # 创建索引

DROP INDEX [indexName] ON mytable;     # 删除索引

SHOW INDEX FROM table_name             # 查看索引

SELECT * FROM TABLE1 FORCE INDEX (FIELD1) …    # 强制索引

SELECT * FROM TABLE1 IGNORE INDEX (idx_)…      # 忽略索引

2.5.2 索引失效

  • 在索引上执行操作时【计算、函数、类型转换等】会导致索引失效

  • 使用不等于(!=或 <>)时无法使用索引会导致全表扫描

  • is null 和 is not null无法使用索引

  • like以通配符开头('%abc'或‘%abc%’)会导致索引失效,导致全表扫描

  • 字符串varchar不加单引号会导致索引失效

  • 用or连接会导致索引失效

  • 使用复合索引索引了多列,没有从最左列索引开始使用,或者跳过了索引中的前面的索引列而使用了后面的索引列【没有使用全部索引】
    如果使用了所有索引【没有缺失】那么sql会自动优化索引顺序,即查询的索引顺序不需要和索引建立的顺序一致,也不存在范围条件右边索引列失效的问题

  • 范围条件右边的索引列会失效

    • 例如:where age > 25 and pos='manager';,则pos上的索引会失效

2.5.3 索引优化

SQL索引失效主要是由于上述8种情况,除了注意避免以上情况导致的索引失效外,还要注意在建立索引上的优化

在建立索引时,要注意以下几种问题:

  • 索引最好设置在经常查询的字段中
  • 使用LEFT JOIN 和RIGHT JOIN 时方向要和索引相反
    - LEFT JOIN主要受右表得影响,因此使用时,index要在右表
    - RIGHT JOIN 主要受左表得影响,因此使用时,index要在左表
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335