MYSQL中InnoDB和ROW_FORMAT=COMPACT-wangqiaowqo-J。。。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.
安装mysql失败每个索引记录包含⼀个五字节的头,在它之前还有⼀个变长的头。这个头是⽤来连接连续的记
录,也⽤于⾏级锁。
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
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论