MySQL的MyISAM引擎现在越来越被淡化了,但是还是有必要再温习总结一下的。

允许你改变语句调度的优先级,它可以使来自多个客户端的查询更好地协作,这样单个客户端就不会由于锁定而等待很长时间。改变优先级还可以确保特定类型的查询被处理得更快。这一部 分讲解MySQL的默认的调度策略和可以用来影响这些策略的选项。它还谈到了并发性插入操作的使用和存储引擎锁定层次对客户端的并发性的影响。为了讨论的 方便,我们把执行检索(SELECT)的客户端称为"读取者",把执行修改操作(DELETE、INSERT、REPLACE或UPDATE)的客户端称 为"写入者"。

MySQL的默认的调度策略可用总结如下:
· 写入操作优先于读取操作。
· 对某张数据表的写入操作某一时刻只能发生一次,写入请求按照它们到达的次序来处理。
· 对某张数据表的多个读取操作可以同时地进行。

  MyISAM和MEMORY存储引擎借助于数据表锁来实现这样的调度策略。当客户端访问某张表的时候,首先必须获取它的锁。当客户端完成对表的 操作的时候,锁就会被解除。通过LOCK TABLES和UNLOCK TABLES语句来显式地获取或释放锁是可行的,但是在通常情况下,服务器的锁管理器会自动地在需要的时候获取锁,在不再需要的时候释放锁。获取的锁的类 型依赖于客户端是写入还是读取操作。

  对某张表进行写入操作的客户端必须拥有独占的(排他的)访问权的锁。操作在进行的过程中,该数据表处于不一致的(inconsistent)状 态,因为数据记录在删除、添加或修改的时候,数据表上的索引也可能需要更新以相互匹配。这个数据表在变化的过程中,如果允许其它的客户端访问,会出现问 题。非常明显,允许两个客户端同时写入一张数据表是不利的,因为这样的操作会很快使数据表中的信息成为一堆无用的垃圾。但是允许客户端读取变化之中的数据 表也不好,因为正在读取的位置中的数据可能正在变化(修改),读取的结果可能不是真实的。

  对某张表执行读取操作的客户端必须获取一个锁,防止在读取的过程中,其它的客户端写入或改变表。但是这个锁不需要独占的访问权。读取操作不会改变数据,因此没有理由让某个读取者阻止其它的读取者访问这张表。因此读取锁允许其它的客户端在同一时刻读取这张表。

MySQL提供了几个语句调节符,允许你修改它的调度策略:
· LOW_PRIORITY关键字应用于DELETE、INSERT、LOAD DATA、REPLACE和UPDATE。
· HIGH_PRIORITY关键字应用于SELECT和INSERT语句。
· DELAYED关键字应用于INSERT和REPLACE语句。

LOW_PRIORITY和HIGH_PRIORITY调节符影响那些使用数据表锁的存储引擎(例如MyISAM和MEMORY)。DELAYED调节符作用于MyISAM和MEMORY数据表。

改变语句调度的优先级
   LOW_PRIORITY关键字影响DELETE、INSERT、LOAD DATA、REPLACE和UPDATE语句的执行调度。通常情况下,某张数据表正在被读取的时候,如果有写入操作到达,那么写入者一直等待读取者完成操 作(查询开始之后就不能中断,因此允许读取者完成操作)。如果写入者正在等待的时候,另一个读取操作到达了,该读取操作也会被阻塞(block),因为默 认的调度策略是写入者优先于读取者。当第一个读取者完成操作的时候,写入者开始操作,并且直到该写入者完成操作,第二个读取者才开始操作。

   如果写入操作是一个LOW_PRIORITY(低优先级)请求,那么系统就不会认为它的优先级高于读取操作。在这种情况下,如果写入者在等待的时候,第 二个读取者到达了,那么就允许第二个读取者插到写入者之前。只有在没有其它的读取者的时候,才允许写入者开始操作。理论上,这种调度修改暗示着,可能存在 LOW_PRIORITY写入操作永远被阻塞的情况。如果前面的读取操作在进行的过程中一直有其它的读取操作到达,那么新的请求都会插入到 LOW_PRIORITY写入操作之前。

  SELECT查询的HIGH_PRIORITY(高优先级)关键字也类似。它允许 SELECT插入正在等待的写入操作之前,即使在正常情况下写入操作的优先级更高。另外一种影响是,高优先级的SELECT在正常的SELECT语句之前 执行,因为这些语句会被写入操作阻塞。

  如果你希望所有支持LOW_PRIORITY选项的语句都默认地按照低优先级来处理,那么请使用--low-priority-updates选项来启动服务器。通过使用INSERT HIGH_PRIORITY来把INSERT语句提高到正常的写入优先级,可以消除该选项对单个INSERT语句的影响。

使用延迟插入操作
  DELAYED调节符应用于INSERT和REPLACE语句。当 DELAYED插入操作到达的时候,服务器把数据行放入一个队列中,并立即给客户端返回一个状态信息,这样客户端就可以在数据表被真正地插入记录之前继续 进行操作了。如果读取者从该数据表中读取数据,队列中的数据就会被保持着,直到没有读取者为止。接着服务器开始插入延迟数据行(delayed-row) 队列中的数据行。在插入操作的同时,服务器还要检查是否有新的读取请求到达和等待。如果有,延迟数据行队列就被挂起,允许读取者继续操作。当没有读取者的 时候,服务器再次开始插入延迟的数据行。这个过程一直进行,直到队列空了为止。

  感觉上LOW_PRIORITY和DELAYED是相 似的,两者都允许数据行插入操作被延迟,但是它们对客户端操作的影响却有很大的差异。LOW_ PRIORITY强迫客户端等待,直到那些数据行可以被插入数据表。DELAYED允许客户端继续操作,服务器在内存中缓冲那些数据行,直到自己有时间处 理它们。

  如果其它的客户端可能运行很长的SELECT语句并且你不希望阻塞,等待插入操作完成的时候,INSERT DELAYED就非常有用处了。客户端提交INSERT DELAYED的时候可能处理得很快,因为服务器只是简单地把要插入的数据行排队。

   但是,你也必须知道正常的INSERT与INSERT DELAYED行为之间的一些其它的差异。如果INSERT DELAYED语句包含语法错误,客户端会得到一个错误,但是却无法得到其它一些在正常情况下可以使用的信息。例如,当语句返回的时候,你无法依赖(得 到)AUTO_INCREMENT(自动增长)值。同样,你无法得到唯一索引的副本数量。发生这种情况的原因在于插入操作在真正地被执行之前已经返回了状 态信息。另一种可能出现的情况是,由于INSERT DELAYED语句的数据行都在内存中排队,当服务器崩溃或者使用kill -9退出的时候,数据行可能丢失(正常情况下,kill -TERM终止命令不会导致这种情况,因为服务器在退出之前会把数据行插入表中)。

使用并发的插入操作
   MyISAM存储引擎有一条例外的规则,它允许读取者阻塞写入者。这种现象发生在MyISAM数据表中间没有"空洞"(可能是删除或更新数据行的结果) 的情况下。当数据表没有"空洞"的时候,任何INSERT语句必然在末尾而不是中部添加数据行。在这种情况下,MySQL允许其它客户端在读取数据的同时 向数据表添加数据行。这就是"并发性插入操作",因为它们同时发生,检索并没有被阻塞。

如果你希望使用并发性插入操作,请注意下面一些事项:
· 在INSERT语句中不要使用LOW_PRIORITY调节符。它会引起INSERT经常被读取者阻塞,因此阻碍了并发性插入操作的执行。
· 如果读取者需要显式地锁定数据表以执行并发性插入操作,就应该使用LOCK TABLES ... READ LOCAL,而不是LOCK TABLES ... READ。LOCAL关键字会获取一个锁,允许并发性操作继续进行,因为它只能应用于数据表中已有的数据行,不会阻塞那些添加到末尾的新数据行。
· LOAD DATA操作应该使用CONCURRENT调节符,允许该数据表上的SELECT语句同时执行。
· 中间包含了"空洞"的MyISAM数据表不能使用并发性插入操作。但是,你可以使用OPTIMIZE TABLE语句来整理该数据表的碎片。----concurrent_insert:0,1,2

锁的层次和并发性
  前面讨论的调度调节符允许你改变默认的调度策略。其中的大部分内容都是介绍使用这些调节符来解决数据表层次(table-level)的锁引起的问题,这都是MyISAM和MEMORY存储引擎用来管理数据表争用的问题的。
   BDB和InnoDB存储引擎实现了不同层次的锁,所以其性能特征和对争用的管理是不同的。BDB引擎使用页面层次(page-level)的锁。 InnoDB引擎使用数据行层次(row-level)的锁,但是只在必要的时候使用(在很多情况下,例如当读取操作都完成的时候,InnoDB可能根本 就不使用锁)。

  存储引擎使用的锁的层次对客户端的并发操作有很大的影响。假设两个客户端都希望更新某个数据表中的一行。由于要执行更新,每个客户端都需要一个写入锁。对于MyISAM数据表,引擎会为第一个客户端分配一个锁,这会引起第二个客户端阻塞,直到第一个客户端完成操作。对于 BDB数据表,它可以实现更大的并发性:两个更新操作会同步进行,除非两个数据行都位于同一个页面中。在InnoDB数据表中,并发性更高;只要两个客户 端没有更新同一行,两个更新操作就能同时发生。

一般的规则是,锁的层次越细微,并发性越好,因为只要客户端使用数据表的部分不同,那么使用表的客户端就可以更多。
· MyISAM检索的速度非常快。但是使用表层次的锁可能成为混合的检索和更新环境中的问题,特别是检索倾向于长时间运行的时候。在这些条件下,更新可能需要等待很久才能进行。
· 当更新操作很多的时候,BDB和InnoDB数据表可以提供更好的性能。由于锁在页面或数据行层次进行,表被锁定的范围较小。这会减少锁的争用,提高并发性。

      在防止死锁(deadlock)方面,表锁比行锁更有优势。使用表锁的时候,死锁不会发生。因为服务器可以通过查看语句来检测需要的数据表,并提前锁定它们。而InnoDB会发生死锁,因为存储引擎没有在事务开始的时候分配所有必要的锁。而是在事务处理的过程中,当检测到需要锁的时候才分配。这就可能出现两个语句获取了锁,接着试图进一步获取锁(需要多个锁),但是这些锁却被对方保持着,等待对方释放。其结果是每个客户端都拥有一个锁,同时还需要利用其它的客户端拥有的锁才能继续执行。这会导致死锁,服务器必须终止其中一个事务。

使用方法:

优先操作 HIGH_PRIORITY
HIGH_PRIORITY可以使用在select和insert操作中,让MYSQL知道,这个操作优先进行。
SELECT HIGH_PRIORITY * FROM TABLE1;

滞后操作 LOW_PRIORITY
LOW_PRIORITY可以使用在insert和update操作中,让mysql知道,这个操作滞后。
update LOW_PRIORITY table1 set field1= where field1= …

延时插入 INSERT DELAYED
INSERT DELAYED INTO table1 set field1= …
INSERT DELAYED INTO 是客户端提交数据给MySQL,MySQL返回OK状态给客户端。而这是并不是已经将数据插入表,而是存储在内存里面等待排队。当mysql有空余时,再插入。另一个重要的好处是,来自许多客户端的插入被集中在一起,并被编写入一个块。这比执行许多独立的插入要快很多。坏处是,不能返回自动递增 的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失。

MyISAM 调度(优先级)的一些优化【转】的更多相关文章

  1. Java多线程-线程的调度(优先级)

    与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...

  2. MySQL的MyISAM和InnoDB对比及优化(转)

    MyISAM和InnoDB是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是 ...

  3. MyISAM引擎的特点及优化方法

    1.什么是MyISAM引擎?MyISAM引擎是MySQL关系数据库管理系统的默认存储引擎(MySQL5.5.5以前),这种MySQL的表存储结构从旧的ISAM代码扩展出许多有用的功能.在存储的时候,每 ...

  4. k8s pod节点调度及k8s资源优化

    一.k8s pod 在节点间调度控制 k8s起pod时,会通过调度器scheduler选择某个节点完成调度,选择在某个节点上完成pod创建.当需要在指定pod运行在某个节点上时,可以通过以下几种方式: ...

  5. MySQL优化篇系列文章(二)——MyISAM表锁与InnoDB锁问题

    我可以和面试官多聊几句吗?只是想... MySQL优化篇系列文章(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. 面试官:咦,小伙子,又来啦 ...

  6. 转: 调整 Linux I/O 调度器优化系统性能

    转自:https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html 调整 ...

  7. Hadoop YARN:调度性能优化实践(转)

    https://tech.meituan.com/2019/08/01/hadoop-yarn-scheduling-performance-optimization-practice.html 文章 ...

  8. Mysql线程池优化笔记

    Mysql线程池优化我是总结了一个站长的3篇文章了,这里我整理到一起来本文章就分为三个优化段了,下面一起来看看.     Mysql线程池系列一(Thread pool FAQ) 首先介绍什么是mys ...

  9. Linux优化之IO子系统监控与调优

    Linux优化之IO子系统 作为服务器主机来讲,最大的两个IO类型 : 1.磁盘IO 2.网络IO 这是我们调整最多的两个部分所在 磁盘IO是如何实现的 在内存调优中,一直在讲到为了加速性能,linu ...

随机推荐

  1. JMX整理

    阅读目录 Standard MBean与MXBean的区别 实现 Notification 认证与授权 JConsole Custom Client What and Why JMX JMX的全称为J ...

  2. 为什么构造器不能是abstract, static, final, native or synchronized的?

    Unlike methods, a constructor cannot be abstract, static, final, native  or synchronized. 1. A const ...

  3. svn搬移到gitlab及使用

    svn是一款非常简便,易用的源代码管理工具,用了这么多年,对它情有独钟.都说习惯最难改,那为何要搬移到gitlab上呢? 喜欢尝试新东西,前提还是git比较强大,svn有的它都有,svn没有的它也有. ...

  4. IGV软件

    它支持各种各样的数据类型,包括基于芯片测序.二代测序数据和基因组注释数据等.整合基因组浏览器(IGV,Integrative Genomics Viewer)进行可视化浏览,它支持各种各式的数据类型, ...

  5. 关于SVN代码提交粒度和频率的思考

    今天组内新来的一个同事问我代码提交频率的问题,他在上家公司是一个模块功能开发自测完成后再提交.而我这边采用的是最少一天提交一次,提倡粒度较小的提交, 而且是基于主干开发.采用这种方式是出于以下几点考虑 ...

  6. ThinkPHP报错处理

    1,当运行结果提示:找不到该页面(控制器),怎么办? 建造一个空页面:EmptyController <?php namespace Home\Controller; use Think\Con ...

  7. mongodb certification

    又偷懒 也有学到不少东西 这个东西算是小结啦 给2013年的碌碌无为挽回点面子 哈哈~

  8. 关于sql用<>不等于查询数据不对问题

    平常查询数据 ' 当想要查询 不等于1 的数据的时候,一般会这样查询 ' 此处查询结果没查到所有想要的结果,如果night_flag 列数据为 null时,此行数据是查询不到的. 解决方法一: ' 解 ...

  9. Sqli-LABS通关笔录-18-审计SQL注入2-HTTP头注入

     在此关卡我学习到了 1.只要跟数据库交互的多观察几遍.特别是对于http头这种类型的注入方式. 2. <?php //including the Mysql connect parameter ...

  10. I2C总线协议的简要说明

    为了快速的了解I2C总线协议,此处采用另类的方式进行说明. 倘若你和另外一个人只能通过一个开关加灯泡的装置在不同的两个房间进行交流,以下是很简单能说明的一个模型: 你的房间有一个开关,另外一间房间有一 ...