《深入浅出Mysql数据库开发、优化与管理维护》笔记
1、优化sql的一般步骤
1.1 使用 show status 命令了解各种sql的执行频率
进入mysql控制台执行
show session status 查询当前连接的统计结果
show global status 查询自数据库上次启动至今的统计结果
或者在操作系统的终端执行
mysqladmin extended-status
可以通过like语句来查询一些特定的内容
比如 show global status like "Com_%";就查看上次启动以来的每个Com_xxx语句执行的次数
Com_select: 执行select查询的次数
Com_insert: 执行insert的次数
Com_update: 执行update的次数
Com_delete: 执行delete的次数
这些参数会都mysql所有存储引擎的表操作都做记录
另外还有专门针对某一些存储引擎的,比如:
Innodb_rows_read
Innodb_rows_insert
Innodb_rows_update
Innobd_rows_delete
通过上面这些数据的比较可以判断数据库是写为主,还是查询为主
关于事务的信息 可以通过 Com_commit 和 Com_rollback 来了解提交和回滚的情况。如果回滚操作非常的频繁,说明应用编写存在很大的问题
另外几个比较重要的,可以展示数据库基本情况的句子:
Connections: 试图连接Mysql数据库的次数
Uptime: 服务器工作时间
Slow_queries: 慢查询的次数
1.2 定位执行效率比较低的sql语句
有两种方法:
一、通过慢查询日志来定位。用--log-slow-queries[=filename]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒得sql语句的日志文件
二、使用show processlist命令查看当前MySQL在进行的线程,包括线程的状态,是否锁表等,可以实时的查看sql的执行情况,同时对一些锁表操作进行优化。
1.3 通过Explain分析低效SQL的执行计划
再通过上面步骤,查到低效率的sql语句之后,可以通过 explain和desc命令获取mysql如何执行select语句的信息,包括select执行过程中表如何连接和连接的顺序。
比如
explain select * from sum(money) from sales a, company b where a.company_id = b.id and a.year = 2006
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
| 1 | SIMPLE | user | system | NULL | NULL | NULL | NULL | 0 | const row not found |
+----+-------------+-------+--------+---------------+------+---------+------+------+---------------------+
1 row in set (0.00 sec)
这个显示的结果是横向的,不够友好,在后面 追加参数“\G”可以每一项一列信息的显示
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: user
type: system
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 0
Extra: const row not found
1 row in set (0.00 sec)
ERROR:
No query specified
上面每一列的含义说明
select_type: 表示select的类型(SIMPLE=>简单表,不使用表连接或者子查询,PRIMARY=>主查询,外层的查询,UNION=>UNION中的第二个或者后面的查询语句,SUBQUERY=>子查询中的第一个select)
table; 输出结果集的表
possible_keys: 表示查询时,可能使用的索引
key: 表示实际使用的索引
key_len: 索引字段的长度
rows; 扫描的行的数量
Extra: 执行情况的说明和描述
type: 表示表的连接类型,性能有好到差的链接类型为:
system=>只有一行,也就是常量表,
const=>单表中最多有一个匹配行,例如primary key或者unique index,
eq_ref=>对于前面的每一行,在此表中只查询一条记录,简单来说,就是多表连接中使用primary key或者unique index,
ref=>与eq_ref类似,区别在于不是使用primay key或者unique index而是使用普通的索引,
ref_or_null=>与ref类似,区别在于条件中包含对null的查询,
index_merge=>索引合并优化,
unique_subquery=>in的后面是一个查询主键字段的子查询,
index_subquery=>与unique_subquery类似,区别在于in的后面是查询非唯一索引字段的子查询,
range=>单表中的查询范围,
index=>对于前面的每一行,都通过查询索引来得到数据,
all=>对于前面的每一行,都通过全表扫描来得到数据
2 索引问题
2.1 索引的存储分类
MyISAM存储索引的表的数据和索引是自动分开存储的,各自是独立的文件
InnoDB存储引擎的表的数据和索引是存储在同一个表的空间里面,但是可以有多个文件组成
Mysql中的存储类型木匾只有两种,BTREE和HASH,具体情况和表的存储引擎有关。
MyISAM和InnoDb存储引擎都支持BTREE索引,
MEMORY/HEAP存储引擎可以支持HASH和BTREE索引
mysql不支持函数索引,但是能对队列的前面的某一部分进行索引,例如name字段,可以只取name的前四个字符来进行索引。
2.2 使用索引
对相关列使用索引是提高select性能的最佳途径
使用索引的条件:a、查询条件中有索引关键字,b、多列索引只有查询条件使用了多列关键字最左边的前缀时,才可以使用索引,否则将不能使用索引。
2.2.1 使用索引
一下情况中会使用到索引:
(1) 多列索引,只要查询的条件中用到了最左边的列,索引一般就会被使用
(2) 对于使用like查询,后面如果是常量,只有%号不在第一个字符时,索引才可能被用到 比如 like "%3" 不会用索引, like "3%"就会走索引
(3) 对大文本进行搜索的时候,使用全文索引,而不是使用 like '%...%'
(4) 如果列名是索引,使用column_name is null将使用索引,
例如: select * from aaa where name is null(name是索引列)
2.2.2 存在索引但不使用索引
在下列情况下,虽然mysql存在索引,但是并不会使用到索引
(1)如果Mysql估计使用索引比全表扫描更慢,则不使用索引。例如如果列key_1 均匀分布在1和100之间,那么查询 select * from table where key_1 > 1 and key_1 < 90;
(2)如果使用MEMPRY/HEAP表并且,where条件中不使用“=”进行索引列,那么不会用到索引。heap表只有在使用“=”的时候,才使用索引
(3)用or隔开的条件,如果or前面的列中有索引,而后面的列中没有索引,那么涉及的索引都不会被用到(or中有一个条件中的列没有索引就用不到索引)
(4)如果不是索引列的第一部分(复合索引的第一部分)
(5)如果like是%开始的
(6)如果列类型是字符串,那么一定记得在where条件中把字符常量值用引号引起来,否则即便是这个列上有索引,也不用用到(比如name字段是字符串的,却写了name=123。要改成“123”)
2.3 查看索引使用情况
如果索引正在工作,Handler_read_key的值将很高,这个值代表了一个行被索引值读的次数,很低得知表明增加索引得到的性能改善不高
Handler_read_rnd_next的值高则意味着查询的效率低效,并且应该建立索引补救。它的含义是:数据文件中读下一行的请求数。如果正在进行大量的表扫描,Handle_read_rnd_next的值较高,则通常说明表索引不正确或者写入的查询没有利用索引
查看方法:show status like 'Handler_read%'
3 简单的优化方法
3.1 定期分析表和检查表
分析表的语法:
analyze [local | no_write_to_binlog] table tab1_name [, ta1_name] ...
用于分析和存储表的关键字分布
分析结果可以使得系统得到更准确地统计信息,使得sql能够正确的执行计划。
如果用户感觉实际执行计划并不是与预期的执行计划,执行一次分析表可能会解决问题。
在分析期间,使用一个读取锁对表进行锁定,这对于MyISAM,BDB和InnoDb表有作用。对于MyISAM表,与使用myisamchk -a 相当
例如:
analyze table user;
mysql> analyze table user;
+------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+---------+----------+----------+
| mysql.user | analyze | status | OK |
+------------+---------+----------+----------+
1 row in set (0.05 sec)
检查表的语法如下:
check table tab1_name [,tab1_name] ... [option] .. option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
作用是:检查一个或者多个表中是否有错误。他对MyISAM和InnoDB表有作用,对于MyISAM表,关键字统计数据被更新。例如:
check table user;
mysql> check table user;
+------------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+-------+----------+----------+
| mysql.user | check | status | OK |
+------------+-------+----------+----------+
1 row in set (0.00 sec)
check table也可以检查视图是否有错误,例如:在视图定义中被引用的表不存在
3.2 定期优化表
语法:
optimize [local | no_write_to_binlog] table tab1_name [, tab1_name] ...
适用范围:
a、删除了表的一部分
b、对含有可变长度行的表(varchar,blob,text列的表)进行了很多更改。
这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费。但是这个命令只对MyISAM,BDB和InnoDb表起作用
mysql> optimize table user;
+------------+----------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+------------+----------+----------+----------+
| mysql.user | optimize | status | OK |
+------------+----------+----------+----------+
1 row in set (0.01 sec)
4 常用SQL的优化
4.1 大批量插入数据
当用load命令导入数据的时候,适当的设置可以提高导入的速度
4.1.1 对于MyISAM存储引擎的表方法如下:
alter table tab_name disable keys;
load the data
alter table tab_name enable keys;
上面操作是打开或者关闭MyISAM表不是唯一索引的更新
ps:导入非空数据表的时候,上面方法很有效,但是导入空表的时候,索引是数据导入完毕之后才去创建的,所以没有影响
4.2.2 对InnoDB表的数据导入
(1)InnoDB类型的表是按照主键的顺序来存储的,所以导入数据按照主键的顺序排列,可以有效的提高导入的效率
(2)在导入数据之前,关闭唯一性校验,set unique_checks=0 ,在导入结束之后设置为 1 开启唯一性校验,可以提高导入效率
(3)如果应用使用自动提交的方式,建议在导入数据的时候执行 set autocomment=0,关闭自动提交,导入结束之后再设置为1,打开自动提交
4.2 优化insert语句
(1)如果是从同一客户那里插入很多航,尽量使用多个值表的insert语句,这种方式将大大的缩短客户端与数据库之间的链接,关闭等资源的消耗,使得效率比分开执行的单个insert语句快
例如:insert to test values(1,2),(1,3),(1,4)....
(2)如果从不同的客户中杀入多行,能通过使用insert delayed语句得到更高的速度。delayed是让insert语句立马执行,四十数据都被放在内存的队列中,并没有真正的写入磁盘,这比每一条数据分别插入快得多。low_priority 刚好想法,是所有其他用户对表的读写完成后才进行插入
(3)将索引文件和数据文件分在不同的磁盘上存放
(4)如果进行批量插入可以增加 bulk_insert_buffer_size 变量值的方法来提高速度,但是这只能对MyIsAM表使用
(5)当一个文本文件装载一个表时,使用 load file insert。这比通常的sql语句快20倍
4.3 优化group by语句
如果查询包括group by但是用户想避免白须结果的小号,可以指定order by null禁止排序
例如:
select id, sum(money) from sale2 group by id order by null
4.4 优化order by语句
可以使用索引来满足一个order by语句
条件:
where条件和order by使用相同的索引,并且order by的顺序和索引顺序相同,并且order by的字段都是升序或者降序
比如: order by key1,key2
where key1=123 order by key1 desc, key2 desc
order by key1 desc, key2 desc
但是以下情况不可以
order by key1 asc, key2 desc 混合使用ASC和DESC
where key2 = 1 , order by key1 查询的关键字和排序的不一样
order by key1,key2 对不同的关键字使用排序
4.5 优化嵌套查询
有些情况下,子查询可以被更加有效的join查询代替
比如 select * from a where b_id not in(select id from b)
换成 select * from a left join b on a.b_id = b.id where a.b_id is not null
4.6 优化OR条件
or的每一个条件都使用索引
但是如果or的几个条件正好是复合索引的元素,则不能起到加速的效果
4.7 使用SQL提示
在sql中加入一些人为的提示来达到优化操作的目的
例如:
select sql_buffer_results * from
这个语句将强行MySql生成一个临时的结果集,只要临时结果集生成之后,所有表上的锁都会被释放。
这能解决遇到表锁问题时,或者要花长时间将结果传给客户端时有所帮助,因为这样可以尽快的释放资源
(1)use index
在查询语句中表名的后面,添加use index来提供希望mysql去参考的索引列表,就可以让mysql不再考虑其他可用的索引
select * from a use index(ind_a_id) where id = 1
(2)ignore index
如果用户只是单纯的想让mysql忽略一个多个索引,则可以使用ignore index作为hint
select * from a ignore index(ind_a_id) where id = 1
(3)force index
强制MySQL使用一个特定的索引,可在查询中使用
分享到:
相关推荐
读书笔记:深入浅出MySQL 数据库开发 优化与管理维护 第2版 唐汉明源码
在MySQL数据库的使用过程中,有多个关键的知识点需要掌握,以保障数据库的高效稳定运行。 首先,MySQL的安装与配置是基础中的基础,这包括了解MySQL的性能优势,以及在Linux环境下如何启动、重启和关闭MySQL服务。...
最详细!! 最简单!!! 最通俗易懂的mysql数据库的学习笔记, 零基础新手小白必备, 少走弯路
深入浅出mysql数据库。内容如下: 1、什么是数据库 2、Mysql相关操作 3、数据库相关操作 4、数据表相关操作 5、mysql中的数据类型 6、mysql数据引擎 7、mysql数据库操作:增删改查、多表联查、聚合函数等用法...
姜承尧作为知名的MySQL专家,他的课程深入浅出地讲解了MySQL的高级概念和技术,帮助DBA(数据库管理员)和开发者提升技能,从而在职场上实现涨薪进阶。这份笔记包含了丰富的知识点,以下是对这些内容的详细阐述: 1...
**MySQL数据库笔记** MySQL是一种广泛使用的开源关系型数据库管理系统(RDBMS),它以其高效、稳定和易用性在全球范围内受到青睐。这份“数据库笔记”深入浅出地介绍了MySQL的各种核心概念和技术,旨在帮助读者全面...
本教程将基于提供的“Mysql+笔记+入门教程+MySQL详细安装图解”资源,深入浅出地介绍MySQL的基础知识、安装过程以及一些实用的开发技巧。 首先,让我们来了解MySQL的基础概念。MySQL基于SQL(结构化查询语言)标准...
MySQL数据库是世界上最受欢迎的开源关系型数据库之一,广泛应用于各种规模的企业、...这份笔记深入浅出地讲解了MySQL数据库的核心知识,适合初学者和有一定经验的开发者作为参考,帮助读者逐步提升在MySQL领域的技能。
推荐的书籍包括《MySQL必知必会》和《MySQL深入浅出》,这两本书可以帮助初学者快速理解和运用MySQL的基本功能。对于进阶学习,可以参考《MySQL排错指南》和《高性能MySQL》。官方文档是学习的重要资源,可以在...
本笔记主要基于《深入浅出MySQL数据库开发、优化与管理维护》一书,旨在帮助个人学习MySQL的基础知识和开发技巧。 MySQL的学习首先从理解数据库的基本概念开始。事务性数据库是指能够支持事务处理的数据库,比如...
《MySQL必知必会》是一本深入浅出的MySQL数据库学习指南,涵盖了MySQL的基础知识、操作技巧以及实际应用。在阅读笔记中,我们将探讨以下几个关键知识点: 1. 数据库概念:MySQL是一种关系型数据库管理系统(RDBMS)...
鲁班学院的这份课堂笔记深入浅出地探讨了MySQL中的核心概念:B+树索引、事务处理以及锁定机制。 一、InnoDB行格式、数据页结构以及索引底层原理分析 InnoDB是MySQL中最常用的存储引擎,它支持事务处理和行级锁定。...
《MySQL数据库应用从入门到精通》是一本深入浅出的MySQL学习资料,涵盖了数据库的基础概念、安装配置、SQL语句的使用以及高级特性的探讨。通过这本书的学习,读者可以了解到MySQL在实际工作中的广泛应用和重要性。...
本笔记将深入浅出地介绍MySQL的基本命令,帮助初学者快速掌握数据库操作。 一、安装与启动MySQL 在安装MySQL后,通常可以通过系统服务或命令行来启动和停止数据库服务。在Windows上,可以使用`net start MySQL`启动...
《MYSQL必知必会》是一本深入浅出介绍MySQL的书籍,旨在帮助读者掌握MySQL的基础知识和高级特性。以下是对这本书中核心知识点的详细解析: 1. **SQL语言基础**: SQL(Structured Query Language)是用于管理关系...
《MySQL 45讲》是一本深入浅出的教程,结合小林coding的《图解MySQL》的解析,可以帮助我们更好地理解和运用这个广泛使用的数据库系统。这份笔记集合了两本书中的精华,并可能加入了作者kwan1117的个人见解和实践...
通过深入浅出的讲解,读者可以学习到如何设计高效的数据模型,优化SQL查询,以及进行数据库的安全管理和备份恢复。此外,本书还会介绍如何在实际项目中应用MySQL,比如在Web开发中的集成和性能调优,从而提升读者的...
在MySQL数据库中,索引是提高查询效率的关键因素。在给定的例子中,表`T`有一个主键`ID`和一个对`k`字段的索引。当我们执行`SELECT * FROM T WHERE k BETWEEN 3 AND 5`时,查询会通过`k`的索引树找到满足条件的记录...
《MySQL必知必会》是一本非常经典的MySQL学习教材,其深入浅出地讲解了数据库管理、查询优化、事务处理等多个关键概念和技术。通过这份学习笔记,我们可以深入了解MySQL的基础知识和高级特性,提升数据库管理与应用...