MYSQL中InnoDB和ROW_FORMAT=COMPACT

去掉:ROW_FORMAT
ALTER TABLE table_name ROW_FORMAT = DEFAULT


MYSQL中InnoDB是什么?
一种表驱动,除了innodb还有其它的,例如isam,myisam等.

innodb的特色在于支持并发与表间引用 MySQL支持多种存储引擎,用户可以方便的选用不同的存储引擎来支持自己的应用,每种不同的存储引擎都有其自己的特性

Innodb是其中的一种存储引擎,它的特性是支持事务,并且采用多版本并发控制的方式来提高并发度主要是事务表,当一个事务全部完成,才会执行update.如果一段代码没有完成(及一个事务操作没有完成)它是不会update的,例如:银行转帐,一 笔业务没有完成的时候,突然的断电,或是,网络,系统的原因使你无法完成此交易的话,这个事务是要回滚的此交易之前的状态的,没有完成交易,你银行的 money是不会减少的!缺点是,innoDB的表执行起来速度较慢,但是安全!bbs的表要求的是速度,用的都是myisam的表!不知这样通俗的说, 你是否理解?
----------------------------------------------------------------------
翻译一段MySQL关于Innodb的物理行结构的官方文档:


Records in InnoDB ROW_FORMAT=COMPACT tables have the following characteristics:

InnoDB ROW_FORMAT=COMPACT 的表,其中的记录有如下特点:


Each index record contains a five-byte header that may be preceded by a variable-length header. The header is used to link together consecutive records, and also in row-level locking.

每个索引记录包含一个五字节的头,在它之前还有一个变长的头。这个头是用来连接连续的记录,也用于行级锁。

The record header contains a bit vector for indicating NULL columns. The bit vector occupies (n_nullable+7)/8 bytes. Columns that are NULL will not occupy other space than the bit in this vector.

记录头包含一个位向量,用来指明空列。位向量占用了(可空的列数+7)/8字节。值为空的列不会再占用此位向量以外的空间。

For each non-NULL variable-length field, the record header contains the length of the column in one or two bytes. Two bytes will only be needed if part of the column is stored externally or the maximum length exceeds 255 bytes and the actual length exceeds 127 bytes.

对于每个非空的变长字段,记录头使用一或两个字节包含了列的长度。只有如下情况才会用到两个字节:字段的值保存在外部;或者字段的最大长度走过了255,并且实际的字段值超过了127字节。

The record header is followed by the data contents of the columns. Columns that are NULL are omitted.

记录头的后面是字段的内容,其中空字段被忽略。

Records in the clustered index contain fields for all user-defined columns. In addition, there is a six-byte field for the transaction ID and a seven-byte field for the roll pointer.

clustered索引的记录包含了所有用户定义的列。此外,还有一个六字节的区域保存事务ID,一个七字节的的区域保存roll pointer(回滚指针?)

If no primary key was defined for a table, each clustered index record also contains a six-byte row ID field.

如果没有定义主键,每个clusterd索引也会包含一个六字节的row ID区域。

Each secondary index record contains also all the fields defined for the clustered index key.

每个副索引(非clustered索引)也包含所有clustered索引键列。

Internally, InnoDB stores fixed-length, fixed-width character columns such as CHAR(10) in a fixed-length format. InnoDB truncates trailing spaces from VARCHAR columns.

内部地,InnoDB用定长的格式存储定长的字符列,如CHAR(10)。InnoDB会去掉VARCHAR列两侧的空格。

Internally, InnoDB attempts to store UTF-8 CHAR(n) columns in n bytes by trimming trailing spaces. In ROW_FORMAT=REDUNDANT, such columns occupy 3*n bytes. The motivation behind reserving the minimum space n is that it in many cases enables an update of the column to be done in place without causing fragmentation of the index page.

内部地,InooDB尝试把UTF-8 CHAR(n)列两侧的空格去掉,使此列只占用n字节。在ROW_FORMAT=REDUNDANT时,这样的列要占用3*n字节。这是为了update该列时在索引页不产生碎片。
---------------------------------------------------------------------
InnoDB性能调节提示
  · 如果Unix的top工具或者Windows任务管理器显示,你的数据库的工作负荷的CPU使用率小于70%,则你的工作负荷可能是磁盘绑定的,可能你正生成太多的事务和提交,或者缓冲池太小。使得缓冲池更大一些会有帮助的,但不要设置缓冲池等于或超过物理内存的80%.
  · 把数个修改放在一个事务里。如果事务对数据库修改,InnoDB在该事务提交时必须刷新日志到磁盘。因为磁盘旋转的速度至多167转/秒,如果磁盘没有骗操作系统的话,这就限制提交的数目为同样的每秒167次。
  · 如果你可以接受损失一些最近的已提交事务,你可以设置参数 innodb_flush_log_at_trx_commit 为 0。无论如何InnoDB试着每秒刷新一次日志,尽管刷新不被许可。
  · 使用大的日志文件,甚至让它与缓冲池一样大。当InnoDB写满日志文件时,它不得不在一个检查点把缓冲池已修改的内容写进磁盘。小日志文件导致许多不必要的吸盘写操作。大日志文件的缺点时恢复时间更长。
  · 也让日志缓冲相当大(与8MB相似的数量)。
  · 如果你存储变长字符串,或者列可能包含很多NULL值,则使用VARCHAR列类型而不是CHAR类型。一个CHAR(N)列总是占据N个字节来存储,即使字符串更短或字符串的值是NULL。越小的表越好地适合缓冲池并且减少磁盘I/O。
  当使用row_format=compact (MySQL 5.1中默认的InnoDB记录格式)和可变长度字符集,比如GB2312或sjis,CHAR(N)将占据可变数量的空间,至少为N 字节。
  · 在一些版本的GNU/Linux和Unix上,用Unix的fsync()(InnoDB默认使用的)把文件刷新到磁盘,并且其他相似的方法是惊人的慢。如果你不满意数据库的写性能,你可以试着设置参数 innodb_flush_method 值为 O_DSYNC,虽然 O_DSYNC 在多数系统上看起来更慢。
  · 当在Solaris 10上,为x86_64架构(AMD Opteron)使用InnoDB存储引擎,重要的是使用forcedirectio选项来安装任何为存储与InnoDB相关的文件而使用的数据系统。(默认在Solaris 10/x86_64上不使用这个文件系统安装选项 )。使用forcedirectio 失败会导致InnoDB在这个平台上的速度和性能严重下降。
  · 当导入数据到InnoDB中之时,请确信MySQL没有允许autocommit模式,因为允许autocommit模式会需要每次插入都要刷新日志到磁盘。要在导入操作规程中禁止autocommit模式,用SET AUTOCOMMIT和COMMIT语句来包住导入语句:
  SET AUTOCOMMIT=0;
  /* SQL import statements ... */
  COMMIT;
  · 如果你使用mysqldump 选项--opt,即使不用SET AUTOCOMMIT和COMMIT语句来包裹,你也使得快速的转储文件被导入到InnoDB表中。
  · 小心大宗插入的大回滚:InnoDB在插入中使用插入缓冲来节约磁盘I/O, 但是在相应的回滚中没有使用这样的机制。一个磁盘绑定的回滚可以用相应插入花费时间的30倍来执行。杀掉数据库进程没有是帮助的,因为回滚在服务器启动时会再次启动。除掉一个失控的回滚的唯一方法是增大缓冲池使得回滚变成CPU绑定且跑得快,或者使用专用步骤,请参阅15.2.8.1节,“强制恢复”。
  · 也要小心其它大的磁盘绑定操作。用 DROP TABLE 或 CREATE TABLE 来清空一个表,而不是用 DELETE FROM tbl_name。
  · 如果你需要插入许多行,则使用多行插入语法来减少客户端和服务器之间的通讯开支:
  INSERT INTO yourtable VALUES (1,2), (5,5), ...;
  这个提示对到任何表类型的插入都是合法的,不仅仅是对InnoDB类型。
  · 如果你在第二个键上有UNIQUE约束,你可以在导入会话中暂时关闭唯一性检查以加速表的导入:
  SET UNIQUE_CHECKS=0;
  对于大表,这节约了大量磁盘I/O,因为InnoDB可以使用它的插入缓冲来在一批内写第二个索引记录。
  · 如果你对你的表有FOREIGN KEY约束,你可以在导入会话过程中通过关闭外键检查来提速表的导入:
  SET FOREIGN_KEY_CHECKS=0;
  对于大表,这可以节约大量的磁盘I/O。
  · 如果你经常有对不经常更新的表的重发查询,请使用查询缓存:
  [mysqld]
  query_cache_type = ON
  query_cache_size = 10M

你可能感兴趣的:(Mysql)