高性能mysql-第一次阅读

读写锁

解决并发控制问题:共享锁(shared lock)和排他锁(exclusive lock),也叫读锁(read lock)和写锁(write lock)。
概念:

  • 读锁是共享的,或者说是相互不阻塞的。多个客户在同一时刻可以同时读取同一个资源,而互不干扰
  • 写锁则是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,这是出于安全策略的考虑,只有这样,才能确保在给定的时间里,只有一个用户能执行,并防止其他用户读取正在写入的统一资源
锁策略
  • 表锁(table lock):表锁是Mysql中最基本的锁策略,并且是开销最小的策略。它会锁定整张表,一个用户在对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这会阻塞其他用户对表的所有读写操作。只有没有写锁时,其他读取的用户才能获取资源。读锁之间是不互相阻塞的。
  • 行级锁(row lock):行级锁可以最大程度的支持并发处理(同时也带来了最大的锁开销),在InnoDB和XtraDB,以及其他一些存储引擎中实现了行级锁。
事务
  • 原子性
  • 一致性
  • 隔离性
  • 持久
隔离级别

在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所作的修改,哪些在事务内和事务间是可见的,哪些是不可兼得。较低级别的通常可以执行更高的并发,系统的开销也更低。

  • READ UNCONNITTED(未提交读):在此级别中,事务的修改,及时没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也称为脏读(Dirty Read)。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不会比其他的级别好太多,但却缺乏其他级别的很多好处,实际应用一般很少使用。
  • READ CONNITTED(提交读):大多数数据库系统的默认隔离级别都是READ COMMITTED(但Mysql不是)。READ COMMITTED满足前面提到的隔离性的简单定义:一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可兼得。这个级别有时候也叫作不可重复读(nonrepeatable read),因此两次执行同样的查询,可能会得到不一样的结果。
  • REPEATABLE READ(可重复读):REPEATABLE READ解决了脏读的问题。该级别保证了在同一个事物中多次读取同样记录的结果是一致的。但是还存在着幻读(Phantom Read)的问题 。幻读:指的是当某个事物在此读取该范围的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行(Phantom Row)。InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)解决了幻读的问题。
  • SERIALIZABLE(可串行化):SERIALIZABLE是最高的隔离级别。它通过强制事务串行执行,避免了幻读的问题。简单来说,SERIALIZABLE会在读取的每一行数据上都枷锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。
  • ANSI SQL 隔离级别
死锁

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源师,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。
死锁发生以后,只有部分或者完全回滚其中一个事务,才能打破死锁。对于事务性的系统,这是无法避免的。所以应用程序在设计时必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。

InnoDB存储引擎

InnoDB是Mysql的默认事务型引擎,也是最重要、只用最广泛的存储引擎。它被设计用来处理大量短期(short-lived)事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB的性能和自动崩溃恢复特性,使得它在非事务型存储的需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB。

服务器性能剖析

我们将性能定义为完成某件任务所需要的时间度量,换句话说,性能即响应时间,这是一个非常重要的原则,我们通过任务和时间而不是资源来测量性能。

  • 性能检测工具—》New Relic 软件即服务(software-as-a-service)
  • 慢查询日志生成剖析报告的工具—》pt-query-digest
Schema与数据类型优化

MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要。

  • 尽量使用可以争取存储数据的最小数据类型。更小的数据类型通常更快,因为他们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少
  • 简单就好。简单数据类型的操作通常需要更少的CPU周期。例如,应该使用MySQL内建的模型(data、time、datetime)而不是字符串来存储日期和时间,应该用整型存储IP地址
  • 尽量避免NULL。如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可谓NULL的列是的索引、索引停机和值比较都更为复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理。如果计划在列上建索引,就应该尽量避免设计成可为NULL的列。

Mysql数据类型比较
VARCHAR和CHAR类型。
VARCHAR

  • VARCHAR类型用于存储可变长字符串,是常见的字符串类型。它比定长类型更节省空间。因为它仅使用必要的空间(越短的字符串使用越少的空间)。有一种情况例外,如果MySQL表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储,这会很浪费空间。
  • VARCHAR需要使用1或2个恶化字节记录字符串的长度:如果列的最大长度小于或等于255字节,则只是用1个字节表示,否则使用2个字节。假设采用latin1字符集,一个VARCHAR(10)的列需要11个字节的存储空间。VARCHAR(1000)的列则需要1002个字节,因为需要2个字节存储长度信息。
  • VARCHAR节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,在UPDATE时可能使行变得比原来更长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理方式是不一样的。例如,MyISAM会将行拆成不同的片段存储,InnoDB则需要分裂页来使行可以放进页内。其他一些存储引擎也许从不在原数据位置更新数据。

CHAR

  • CHAR类型是定长的:MySQL总是根据定义的字符串长度分配足够的空间。 当存储CHAR值时,MySQL会删除所有的末尾空格。CHAR值会根据需要采用空格进行填充以方便比较。CAHR适合存储很短的字符串,或者所有值都接近同一个长度。例如,CHAR非常适合存储密码的MD5值,因为这是一个定长的值。对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。对于非常短的列,CHAR比VARCHAR在存储空间上也更有效率 。
创建高性能的索引

索引的类型

  • B-Tree索引:B-Tree索引适用于全键值、键值范围或键前缀查找。其中键前缀查找只适用于最左前缀的查找。
  • 哈希索引:基于哈希表实现,只有精确匹配索引所有列的查询才有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值