• MyISAM与InnoDB两者之间区别与选择(转)


    Mysql在V5.1之前默认存储引擎是MyISAM;在此之后默认存储引擎是InnoDB

    MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合。

    InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和delete,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。

    事务

    MyISAM不支持事务,InnoDB是事务类型的存储引擎,当我们的表需要用到事务支持的时候,那肯定是不能选择MyISAM了。

    锁表

    MyISAM只支持表级锁,BDB支持页级锁和表级锁默认为页级锁,而InnoDB支持行级锁和表级锁默认为行级锁。
     
    表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许
     
    MyISAM是表级锁定的存储引擎,它不会出现死锁问题
     
    对于write,表锁定原理如下:
     
    如果表上没有锁,在其上面放置一个写锁,否则,把锁定请求放在写锁队列中。
     
    对于read,表锁定原理如下 :
     
    如果表上没有写锁定,那么把一个读锁放在其上面,否则把锁请求放在读锁定队列中
     
    当一个锁定被释放时,表可被写锁定队列中的线程得到,然后才是读锁定队列中的线程。这意味着,如果你在一个表上有许多更新,那么你的SELECT语句将等到所有的写锁定线程执行完。

    行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。
     
    行级锁是Mysql粒度最小的一种锁,它能大大的减少数据库操作的冲突,但是粒度越小实现成本也越大。
     
    行级锁可能会导致“死锁”,那到底是怎么导致的呢,分析原因:Mysql行级锁并不是直接锁记录,而是锁索引。索引分为主键索引和非主键索引两种,如果一条sql语句操作了主键索引,那么Mysql就会锁定这个主键索引,如果sql语句操作的是非主键索引,那么Mysql会先锁定这个非主键索引,再去锁定主键索引。
     
    在UPDATE 和 DELETE操作时Mysql不仅会锁定所有WHERE 条件扫描过得索引,还会锁定相邻的键值。
     
    “死锁”举例分析:
     
    表Test:(ID,STATE,TIME)  主键索引:ID  非主键索引:STATE
     
    当执行"UPDATE  STATE =1011 WHERE STATE=1000"  语句的时候会锁定STATE索引,由于STATE 是非主键索引,所以Mysql还会去请求锁定ID索引
     
    当另一个SQL语句与语句1几乎同时执行时:“UPDATE STATE=1010 WHERE ID=1”  对于语句2 Mysql会先锁定ID索引,由于语句2操作了STATE字段,所以Mysql还会请求锁定STATE索引。这时。彼此锁定着对方需要的索引,又都在等待对方释放锁定。所以出现了"死锁"的情况。
     
    行级锁的优点:
     
    有许多线程访问不同的行时,只存在少量的冲突。
     
    回滚时只有少量的更改
     
    可以长时间锁定单一的行
     
    行级锁缺点:
     
    相对于页级锁和表级锁来说占用了更多的内存
     
    当表的大部分行在使用时,比页级锁和表级锁慢,因为你必须获得更多的锁
     
    当在大部分数据上经常使用GROUP BY操作,肯定会比表级锁和页级锁慢。
     
    页级锁:表级锁速度快,但是冲突多;行级锁速度慢,但冲突少;页级锁就是他俩折中的,一次锁定相邻的一组记录。

    外键

    MyISAM引擎不支持外键,InnoDB支持外键

    其他

    • 对于count()查询来说MyISAM更有优势,这是因为MyISAM中保存表的具体行数,而InnoDB 中不保存,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。需要注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。 
    • InnoDB是为处理巨大数据量时的最大性能设计,它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 InnoDB 把数据和索引存放在表空间里,可能包含多个文件,这与其它的不一样,举例来说,在 MyISAM 中,表被存放在单独的文件中。InnoDB 表的大小只受限于操作系统的文件大小,一般为 2 GB。 InnoDB所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件,或者是独立的表空间文件),相对来说比较不好备份,免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump。  
    • MyISAM支持全文索引(FULLTEXT),InnoDB不支持。
    • MyISAM引擎的表的查询、更新、插入的效率要比InnoDB高。 

    至于怎么选择存储引擎:

    思考几个问题:

    ◆你的数据库有外键吗?   

    ◆你需要事务支持吗?   

    ◆你需要全文索引吗?   

    ◆你经常使用什么样的查询模式?   

    ◆你的数据有多大?   

    如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式。如果你需要全文索引,那么通常来说 MyISAM是好的选择,因为这是系统内建的。

    数据的大小,是一个影响你选择什么样存储引擎的重要因素,大尺寸的数据集趋向于选择InnoDB方式,因为其支持事务处理和故障恢复。数据库的大小决定了故障恢复的时间长短,InnoDB可以利用事务日志进行数据恢复,这会比较快。而MyISAM可能会需要几个小时甚至几天来干这些事,InnoDB只需要几分钟。  

    操作数据库表的习惯可能也会是一个对性能影响很大的因素。比如: COUNT() 在 MyISAM 表中会非常快,而在InnoDB 表下可能会很痛苦。而主键查询则在InnoDB下会相当相当的快,但需要小心的是如果我们的主键太长了也会导致性能问题。大批的inserts 语句在 MyISAM下会快一些,但是updates 在InnoDB下会更快一些——尤其在并发量大的时候。  
      
    所以,到底你检使用哪一个呢?根据经验来看,如果是一些小型的应用或项目,那么MyISAM 也许会更适合。当然,在大型的环境下使用 MyISAM 也会有很大成功的时候,但却不总是这样的。如果你正在计划使用一个超大数据量的项目,而且需要事务处理或外键支持,那么你真的应该直接使用 InnoDB方式。但需要记住InnoDB 的表需要更多的内存和存储,转换100GB 的MyISAM 表到InnoDB 表可能会让你有非常坏的体验。  

    总结一下,在写多读少的应用中还是Innodb插入性能更稳定,InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力 (crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表, InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non- locking read in SELECTs)。这些特性均提高了多用户并发操作的性能表现。如果是对读取速度要求比较快的应用还是选MyISAM。

    转自:https://www.cnblogs.com/y-rong/p/8110596.html

  • 相关阅读:
    URAL——DFS找规律——Nudnik Photographer
    URAL1353——DP——Milliard Vasya's Function
    URAL1203——DPor贪心——Scientific Conference
    递推DP HDOJ 5389 Zero Escape
    区间DP UVA 1351 String Compression
    树形DP UVA 1292 Strategic game
    Manacher HDOJ 5371 Hotaru's problem
    同余模定理 HDOJ 5373 The shortest problem
    递推DP HDOJ 5375 Gray code
    最大子序列和 HDOJ 1003 Max Sum
  • 原文地址:https://www.cnblogs.com/xulan0922/p/12074573.html
Copyright © 2020-2023  润新知