给大家分享一下------mysql的优化

MySQL 优化专题拓展

--王耀宇

 

一、SQL优化

1、分析和定位策略

1、通过 show status 了解各种 SQL 的执行频率

2、定位执行效率低的 SQL 语句:①通过慢日志定位;②使用 show processlist 命令查看当前在进行的线程

3、通过 explain 分析低效 SQL

4、通过 show profile 分析 SQL

5、通过 trace 分析优化器的选择

2、优化

1、大批量插入数据,使用如下方式能快速导入大量数据(在 myisam 引擎下速度更为显著):

alter table 表名 disable keys; Loading the data

Alter table 表名 enable keys;

2、优化 insert 语句:

①对同一客户插入很多行,尽量使用多个值表的 insert 语句,能大大缩减客户端与数据库之间的连接。例如 insert into 表名 values(1,2),(1,3),(1,4)····

②对不同客户插入很多行,可以使用 insert delayed 语句更高速

③将索引文件和数据文件分在不同的磁盘上存放

④从一个文本文件装载一个表时,使用 load data infile,速度会比 insert 快 20 倍左右

3、优化 order by 语句:

①mysql 中的两种排序方式:第一种是有序索引顺序扫描直接返回有序数据;第二种是

通过对返回数据进行排序(Filesort 排序)

②Filesort 优化:通过两次扫描算法和一次扫描算法

4、优化 group by 语句:使用 group by null 可以避免用户排序结果的消耗。

5、优化嵌套查询:子查询可以一次性完成多个步骤查询,同时可以避免事务或者是表死锁。

但是在有些情况下,连接查询可以代替子查询。

6、优化 or 条件:正确使用 or 条件查询,当时在对有独立索引的列查询时 or 操作能够快速

查找到结果;而在对有复合索引的列上做 or 操作时,却不能用到索引

7、优化分页查询:

①思路一:在索引上完成排序分页的操作,最后根据主键关联回原表查询所需要的其他列内容,这种方式让 mysql 扫描尽可能少的页面来提高分页效率

②思路二:把 limit 查询转换成某个位置查询。这样把 limit m,n 转换成 limit n 只适合在

排序字段不会出现重复值的环境下

8、使用 SQL 提示:

①use index:在查询语句中表名的后面,添加 use index 来提供 mysql 去参考的索引列表,让 mysql 不再去考虑其他索引

②ignore index:使用 ignore index 可以让 mysql 忽略一个或者多个索引

③force index:强制 mysql 使用一个特定的索引,一定情况下可以避免全秒扫描

二.索引问题

1、索引的存储分类

①B-Tree 索引:最常见的索引,大部分引擎都支持

②Hash 索引:只有 memory 引擎支持

③R-Tree 索引(空间索引):使用很少,只做了解

④Full-text(全文索引):主要用于全文索引,innodb 从 mysql5.6 开始提供支持

2、Mysql 中使用索引的场景

①匹配全值:对索引中所有列都指定具体值,即对索引中的所有列都有等值匹配的条件

例:select * from rental where rental_date=’2017-06-27 17:40:59’ and customer_id=343;

②匹配值的范围查询:对索引的值能够进行范围查找

例:select * from rental where customer_id>=373 and customer_id<400;

③匹配最左前缀:仅仅使用索引中的最左边列进行查找。

例:在 A+B+C 字段上的联合索引能够被 A、A+B、A+B+C 的等值查询利用,但是不能被B、B+C 的等值查询利用到。

④仅仅对索引进行查询,档查询的列都在索引的字段中时,查询的效率更高

⑤匹配列前缀:仅仅使用索引中的第一列,并且只包含索引第一列的开头一部分进行查

⑥索引匹配部分精确而其他部分进行范围匹配:

例:select a_id from rental where rental_date=’2006-02-14’ and customer_id >=300 and customer_id < 400

⑦如果列名是索引,那么使用 column_name is null 就会使用索引

3、存在索引但不能使用索引的场景

①以%开头的 Like 查询不能够利用索引

②数据类型出现隐式转换的时候也不会使用索引,特别是当列类型是字符串,一定要在 where 条件中把字符串常量值用引号引起来,否则即便是有索引也是无效的

③复合索引的情况下,假如查询条件不满足最左原则,是不会使用索引的

④如果 mysql 估计使用索引比全表扫描更慢,则不使用索引

⑤用 or 分割开的条件,如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到

三、优化数据库对象

1、优化表的数据类型:表需要使用何种数据类型是需要根据应用来判断的。可以使用函数 procedure analyse()对当前应用的表进行分析,可以根据当前表提出优化建议

2、通过拆分提高表的访问效率:

①垂直拆分:把主码和一些列放到一个表,然后把主码和另外的列放到另一个表中

②水平拆分:根据一列或多列的值把数据行放到两个独立的表中

3、使用中间表提高统计查询速度:

①中间表复制源表部分数据,并且与源表相“隔离”,在中间表上做统计查询不会对在 线用户产生负面影响

②中间表上可以灵活地添加索引或者增加临时用的新字段,从而达到提高统计查询效率 和辅助统计查询作用

四、锁问题

 

1、MySQL 的 3 种锁

①表(级)锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突概率最高, 并发度最低(MyISAM,锁住整个表,可同时读,不可写)

②行(级)锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突概率最低,并 发度也最高(InnoDB,单独的一行记录加锁)

③页面锁:开销和加锁时间介于表锁和行锁之间;会出现死锁;锁定粒度介于表锁和行 锁之间,并发度一般

2、MyISAM 的表级锁

①两种模式: 表共享读锁(所有用户可以同时去读同一个加了该表锁的表,但是不能去对其进行 其他操作)

表独占写锁(一个用户在对加了该表锁的表进行写操作的时候,其他用户不能对其 进行操作)。MyISAM 表的读操作与写操作之间,以及写操作之间是串行的,只允许上述其 中一种操作进行

②加锁:MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执 行更新操作(UPDATE、DELETE、INSERT 等)前,会自动给涉及的表加写锁,这个过程并不 需要用户干预,都是由 MyISAM 引擎自动完成加锁

③MyISAM 锁调度:MyISAM 存储引擎的读锁和写锁是互斥的,读写操作是串行的。当 一个进程请求某个 MyISAM 表的读锁,同时另一个进程也请求同一表的写锁,此时 MySQL 会让写进程先获得锁。不仅如此,即使读请求先到锁等待队列,写请求后到,写锁也会插到 读锁请求之前

3、InnoDB 的锁

①几种锁模式:

共享锁(S 锁):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁

排它锁(X 锁):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集 的共享读锁和排他写锁。另外,为了允许行锁和表锁共存,实现多粒度锁机制

意向共享锁(IS 锁):事务打算给数据行加行共享锁,事务在给一个数据行加共享 锁前必须先取得该表的IS 锁。

意向排它锁(IX 锁):事务打算给数据行加行排他锁,事务在给一个数据行加排他 锁前必须先取得该表的 IX 锁。

②加锁方式:意向锁是 InnoDB 自动加的,不需用户干预。对于 UPDATE、DELETE 和 INSERT 语句,InnoDB 会自动给涉及数据集加排他锁(X);对于普通 SELECT 语句,InnoDB 不会加任何锁

③在不通过索引条件查询的时候,InnoDB 确实使用的是表锁,而不是行锁

④由于 MySQL 的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同 行的记录,但是如果是使用相同的索引键,是会出现锁冲突 北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090

⑤当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论 是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁。

4、锁使用总结:

①表锁更适合与以查询为主,只有少量按索引条件更新数据的应用,如 Web 应用;

②行锁更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用, 入一些在线事务处理;

五、应用优化

 

1.使用连接池

连接池:需要访问数据库的的地方,都已经预先创建好,可以直接获取链接,分配给应用使 用,大大减少了创建新连接所耗费的资源。在访问结束后,链接将重新交还给连接池,以供新访问使用

2、减少对 mysql 的访问

①避免对同一数据做重复检索

②使用查询缓存(query cache)

③增加 cache 层 PS:第③个和第②个作用差不多,只是 cache 层比 query cache 要更大,层次要深点,cache 层可以看做是 mysql 的二级数据库,query cache 相当于 mysql 内部的缓存

3、负载均衡:是重用的一种优化方式,采用某种均衡算法,将固定的负载量分布到不同的 服务器上,以此来减轻单台服务器的负载均衡,达到优化的目的。

①利用 mysql 复制分流查询操作:一个主服务器承担更多操作,而多台从服务器承担产查询 操作,主从之间通过复制实现数据的同步。多台从服务器一方面用来确保可用性,一方面可 以创建不同的索引以满足不同的查询的需要。

②采用分布式数据库架构:分布式的数据库架构适合大数据量、负载高的情况,它具有良好 的扩展性和高可用性。(该情况只支持 innodb 存储引擎)

4、其他优化措施

①对于没有删除行操作的 myisam 表,插入操作和查询操作可以并行进行,因为没有删除操 作的表查询期间不会阻塞插入操作

②充分利用列有默认值的事实,只有当插入的值不同于默认值时,才明确地插入值。这会减 少 mysql 需要做的语法分析从而提升插入速度

③表的字段尽量不使用自增长变量,在高并发的情况下该字段的自增长可能对效率有比较大的影响

概念补充

①更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该 行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更新覆盖 了由其他事务所做的更新。

②脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条 记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第 二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。 这种现象被形象地叫做"脏读"。

③不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读 取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种 现象就叫做“不可重复读”。 北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090

④幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发 现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。

⑤死锁(Deadlock):是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种 互相等待的现象,这些永远在互相等待的进程称为死锁进程。表级锁不会产生死锁,所以解 决死锁主要还是真对于最常用的 InnoDB。 PS:在读取数据前,对其加锁,阻止其他事务对数据进行修改可避免脏读、不可重复读、幻读

⑥悲观锁(Pessimistic Lock):悲观锁的特点是先获取锁,再进行业务操作,即“悲观”的 认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作

⑦乐观锁(Optimistic Lock):乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即 “乐观”的认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步 再去拿一下锁就好

⑧热备份:热备份是在数据库运行的情况下,备份数据库的方法。即热备份是系统处于正常 运转状态下的备份

⑨冷备份:冷备份发生在数据库已经正常关闭的情况下,当正常关闭时会提供一个完整的数 据库。冷备份时将关键性文件拷贝到另外的位置的一种说法。冷备份是最快和最安全的方法。

时间: 2024-10-22 14:48:31

给大家分享一下------mysql的优化的相关文章

MySQL 性能优化的最佳20多条经验分享

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的                    事,而这更是我们程序员需要去关注的事情. 当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语                句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的M

20多条MySQL 性能优化经验分享

当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的.当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了. 这里最主要

MySQL通用优化技巧 | Ucloud运维在线微信群分享

MySQL通用优化技巧 | Ucloud运维在线微信群分享 2015-09-17 MySQL中文网 本文根据DevOps华南运维圈@UCloud微信群「大话运维」的嘉宾分享整理而成.「大话运维」将邀请业界运维前线技术专家作为分享嘉宾,分享技术趋势和技术实战,为运维朋友提供各种踩坑.躲坑.绕坑新技能. 嘉宾介绍 叶金荣Oracle MySQL ACE,国内最早的MySQL推广者.2006年创办国内首个MySQL专业技术网站 MySQL 中文网.资深MySQL专家,10余年MySQL经验,擅长Mys

MySQL 性能优化的最佳20多条经验分享[转]

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情. 当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被M

淘宝内部分享:MySQL &amp; MariaDB性能优化

淘宝内部分享:MySQL & MariaDB性能优化 发表于2015-01-20 16:26| 17496次阅读| 来源mysql.taobao.org| 21 条评论| 作者淘宝数据库团队 MySQL性能优化淘宝数据库 摘要:MySQL是目前使用最多的开源数据库,但是MySQL数据库的默认设置性能非常的差,必须进行不断的优化,而优化是一个复杂的任务,本文描述淘宝数据库团队针对MySQL相关的数据库优化方案. 编者按:MySQL是目前使用最多的开源数据库,但是MySQL数据库的默认设置性能非常的

MYSQL性能优化分享(分库分表)

MYSQL性能优化之分库分表与不停机修改mysql表结构,需要的朋友可以参考下 1.分库分表 很明显,一个主表(也就是很重要的表,例如用户表)无限制的增长势必严重影响性能,分库与分表是一个很不错的解决途径,也就是性能优化途径,现在的案例是我们有一个1000多万条记录的用户表company,查询起来非常之慢,同事的做法是将其散列到100个表中,分别从company0到company99,然后根据id分发记录到这些表中,牛逼的代码大概是这样子: 复制代码代码如下: <?php for($i=0;$i

中国移动MySQL数据库优化最佳实践

原创 2016-08-12 章颖 DBAplus社群 本文根据DBAplus社群第69期线上分享整理而成,文末还有书送哦~ 讲师介绍章颖 数据研发工程师 现任中国移动杭州研发中心数据研发工程师,擅长MySQL故障诊断,性能调优,MySQL高可用技术,曾任中国电信综合平台开发运营中心DBA 开源数据库MySQL比较容易碰到性能瓶颈,为此经常需要对MySQL数据库进行优化,而MySQL数据库优化需要运维DBA与相关开发共同参与,其中MySQL参数及服务器配置优化主要由运维DBA完成,开发则需要从数据

干货分享:MySQL之化险为夷的【钻石】抢购风暴

抢购钻石不稀奇,稀奇的是有钱赚不到,事情发生在2015年5月20日,大好的日子自然少不了商家的参与.即可为您还原现场,解决思路献给各位,请欣赏Show Time,everybody~ 1.优化起因及工作准备 2014年5月20日下午三点四十接到对方不愿意透漏姓名的“王大锤”领导的电话,对方火急火燎的仅提供了网站访问慢一条信息,当时博主那个心里一万只XX奔腾而过,俗话说的好,酒肉穿肠过,拿人钱财必替人消灾. 对博主来说网站访问慢,首先不能乱了阵脚,先想到的就是看web.先看静态,如果静态ok就看动

MYSQL之性能优化 ----MySQL性能优化必备25条

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过 多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这些优化技巧对你有用. 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效的方法之一,而且这是被