怎么进行mysql数据库优化?

怎么进行mysql数据库优化?,第1张

有八个方面可以对mysql进行优化:

1、选取最适用的字段属性

MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。

2. 使用连接(JOIN)来代替子查询(Sub-Queries)

MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。

3、使用联合(UNION)来代替手动创建的临时表

MySQL从4.0的版本开始支持union查询,它可以把需要使用临时表的两条或更多的select查询合并的一个查询中。在客户端的查询会话结束的时候,临时表会被自动删除,从而保证数据库整齐、高效。

4、事务

尽管我们可以使用子查询(Sub-Queries)、连接(JOIN)和联合(UNION)来创建各种各样的查询,但不是所有的数据库 *** 作都可以只用一条或少数几条SQL语句就可以完成的。更多的时候是需要用到一系列的语句来完成某种工作。但是在这种情况下,当这个语句块中的某一条语句运行出错的时候,整个语句块的 *** 作就会变得不确定起来。设想一下,要把某个数据同时插入两个相关联的表中,可能会出现这样的情况:第一个表中成功更新后,数据库突然出现意外状况,造成第二个表中的 *** 作没有完成,这样,就会造成数据的不完整,甚至会破坏数据库中的数据。要避免这种情况,就应该使用事务,它的作用是:要么语句块中每条语句都 *** 作成功,要么都失败

5、锁定表

尽管事务是维护数据库完整性的一个非常好的方法,但却因为它的独占性,有时会影响数据库的性能,尤其是在很大的应用系统中。由于在事务执行的过程中,数据库将会被锁定,因此其它的用户请求只能暂时等待直到该事务结束。其实,有些情况下我们可以通过锁定表的方法来获得更好的性能。

6、使用外键

锁定表的方法可以维护数据的完整性,但是它却不能保证数据的关联性。这个时候我们就可以使用外键。

7、使用索引

索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快得多的速度检索特定的行,尤其是在查询语句当中包含有MAX(),MIN()和ORDERBY这些命令的时候,性能提高更为明显。

8、优化的查询语句

绝大多数情况下,使用索引可以提高查询的速度,但如果SQL语句使用不恰当的话,索引将无法发挥它应有的作用。

在项目的一次需求中,需要对一个表增加字段,然而在执行增加字段的sql语句时,卡住了很久都没提交到Mysql完成,而此时对外接口服务请求也卡住了,这时中断卡住的alter table 语句,服务慢慢恢复正常,如果不搞清楚这个问题的根源,不敢增加字段,因为会直接影响到服务

通过show processlist 查看到在alter table语句执行卡住过程中,累计了大量状态为 Waiting for table metadata lock 的记录

然后查看当前的事务状态 执行 select * from information_schema.innodb_trx\G

发现了其中一条已经运行了很久的事务,我怀疑跟这个运行很久的而且没有提交的事务有关。

在本地mysql开多个终端测试

session 1: 开启事务,执行select 语句,但不提交事务

session 2:执行增加字段sql

执行被阻塞了

可以看到alter table语句的状态为Waiting for table metadata lock

session 3 : 再次查询t1表

也被阻塞了

select * from t1 再次查询t1表也是 Waiting for table metadata lock状态,说明由于 metadata lock的存在,会导致后面正常的查询都会因为等待锁而阻塞

再查看当前事务运行状态:

可以看到,session1的事务由于还没提交,所以这里能看到它的状态还是running

这时我们commit session1的事务,看看效果

session 1:

session 2:

session 3:

可以看到session1的事务提交后,session2 和session3 都正常执行了, 他们完成的时间分别是30秒和7秒

通过上面的还原测试,可以知道是由于事务没有提交而给表加了锁,导致后面alter语句因为等待锁而阻塞,从而影响后面的正常请求。

那说明我们的项目是默认开启了事务吗?

继续排查,项目是使用flask-sqlchemy的插件来管理mysql接入,然后查了下文档

在实例化sqlchemy的时候,会创建一个用于跟Mysql交互的session对象,看看源码

从 SignallingSession类的定义看来,autocommit=False,说明默认都给所有的sql执行开启事务,也就是说,哪怕是纯select语句,不需要加锁的select,我们的项目默认也需要开启事务,这对于Mysql MVCC的版本控制来说,是没必要的。

解决办法:就是在实例化SQLAlchemy的时候,给一个参数,修改的session的autocommit=True:

来自官网的介绍:

意思就是为了保证事务的串行执行,而启用的一个锁,这个锁只会在事务结束的时候释放,因此在事务提交或回滚钱,任何对这个表做的DDL *** 作,都是会阻塞的

这个 Metadata lock 是MySQL在5.5.3版本后引入了,为的是防止5.5.3以前的一个bug的出现:

当一个会话在主库执行DML *** 作还没提交时,另一个会话对同一个对象执行了DDL *** 作如drop table,而由于MySQL的binlog是基于事务提交的先后顺序进行记录的,因此在从库上应用时,就出现Q了先drop table,然后再向table中insert的情况,导致从库应用出错。

大家好,我是Tom哥~

为了便于大家查找问题,了解全貌,整理个目录,我们可以快速全局了解关于mysql数据库,面试官一般喜欢问哪些问题

接下来,我们逐条来看看每个问题及答案

MyISAM 和 InnoDB 的区别?

答案:InnoDB 支持 事务、外键、聚集索引,通过MVCC来支持高并发,索引和数据存储在一起。InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数。

InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁,并发能力低。MySQL 将默认存储引擎是 InnoDB

mysql 锁有哪些类型?

答案:mysql锁分为共享锁( S lock ) 、排他锁 ( X lock ),也叫做读锁和写锁。根据粒度,可以分为表锁、页锁、行锁。

什么是间隙锁?

答案:间隙锁是可重复读级别下才会有的锁,mysql会帮我们生成了若干 左开右闭 的区间,结合MVCC和间隙锁可以解决幻读问题。

如何避免死锁?

答案:死锁的四个必要条件:1、互斥 2、请求与保持 3、环路等待 4、不可剥夺。

数据库的隔离级别?

答案:读未提交、读已提交、可重复读(mysql的默认级别,每次读取结果都一样,但是有可能产生幻读)、串行化。

Mysql有哪些类型的索引?

答案:

什么是覆盖索引和回表?

答案:

1、覆盖索引,指的是在一次查询中,一个索引包含所有需要查询的字段的值,可能是返回值或where条件

假如我们创建了一个(money,buyer_id)的联合索引,索引的叶子节点包含了 buyer_id 的信息,则不会再 回表 查询。

2、回表,指查询时一些字段值拿不到,需要到主键索引B+树再查一次。

Mysql的最左前缀原则?

答案:即最左优先,在检索数据时从联合索引的最左边开始匹配,直到遇到范围查询(如:>、<、between、like等)

例子:where a = 1 and b = 2 and c >3 and d = 4 ,如果建立(a,b,c,d)组合索引,d是用不到索引的;如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。

线上SQL的调优经验?

答案:

官方为什么建议采用自增id 作为主键?

答案:自增id是连续的,插入过程也是顺序的,总是插入在最后,减少了页分裂,有效减少数据的移动。所以尽量不要使用字符串(如:UUID)作为主键。

索引为什么采用B+树,而不用B-树,红黑树?

答案:提升查询速度,首先要减少磁盘IO次数,也就是要降低树的高度。

事务的特性有哪些?

答案:ACID。

如何实现分布式事务?

答案:

日常工作中,MySQL 如何做优化?

答案:

mysql 主从同步具体过程?

答案:

什么是主从延迟?

答案:指一个写入SQL *** 作在主库执行完后,将数据完整同步到从库会有一个时间差,称之为主从延迟。计算公式:

注意:不同服务器要保持时钟一致

主从延迟排查方法?

答案:通过 show slave status 命令输出的 Seconds_Behind_Master 参数的值来判断

主从延迟要怎么解决?

答案:

如果数据量太大怎么办?

答案:mysql表的数据量一般控制在千万级别,如果再大的话,就要考虑分库分表。除了分表外,列举了面对海量数据业务的一些常见优化手段

分表后ID如何保证全局唯一呢?

答案:分库分表后,多张表共用一套全局id,原来单表主键自增方式满足不了要求。我们需要重新设计一套id生成器。特点:全局唯一、高性能、高可用、方便接入。

分表后可能遇到的哪些问题?

答案:分表后,与单表的最大区别是有分表键 sharding_key ,用来路由具体的物理表,以电商为例,有买家和卖家两个维度,以 buyer_id 路由,无法满足卖家的需求,反之同样道理。如何解决?


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7438736.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存