标签:查询 拷贝 不用 创建 系统表 架构 工作 建议 变化
OPTIMIZE TABLE
语句来重组表,压缩浪费的表空间。这是在其它优化技术不可用的情况下最直接的方法。OPTIMIZE TABLE
语句通过拷贝表数据并重建表索引,使得索引数据更加紧凑,减少空间碎片。语句的执行效果会因表的不同而不同。过大的表或者过大的索引及初次添加大量数据的情况下都会使得这一操作变慢。
InnoDB
表,如果主键过长(长数据列做主键,或者多个列组合做主键)会浪费很多空间。同时,二级索引也包含主键。这种情况,可以考虑创建自增列作为主键,或者使用前缀索引。VARCHAR
代替 CHAR
。在小表应用上,缓存使用及磁盘I/O消耗会更小。COMPRESSED
和的不同性能影响。优化InnoDB
事务处理,主要需要找到事务特性和服务器负载间的某个平衡点。例如,一秒需要提交几千事务的,或者每隔2-3个小时提交一次事务的不同应用表现。
AUTOCOMMIT=1
会限制繁忙数据库的性能。如果可以的话,可以在应用中使用SET AUTOCOMMIT=0
或者 START TRANSACTION
,然后将多个相关的数据变更操作添加到同一事务中,然后执行COMMIT
语句来提交事务,提交数据变更。InnoDB
对于引发数据库变更的操作,必须将其进行日志刷盘。
SELECT
语句的事务,启用 AUTOCOMMIT
,使得 InnoDB
能够识别只读事务,然后进行相应的优化。可以通过如下策略减少此类问题发生:
innodb_change_buffering=all
,这样update和delete操作也会和insert一样进行缓存,回滚也更快。为了避免时空的回滚。增大缓存,使得回滚进程可以应用到最大的资源以便快速执行。或者杀掉回滚进程,然后使用innodb_force_recovery=3
选项重启。
对于较多执行耗时inserts, updates, 及deletes 操作的服务器,确保innodb_change_buffering=all
开启。
InnoDB
如会每秒刷盘一次日志,如果可以承受最新事务崩溃的数据损失,可以设置innodb_flush_log_at_trx_commit
= 0。虽然日志的刷盘操作也不是保证的,同时也可以设置innodb_support_xa
= 0,减少磁盘和二进制日志的同步操作。Note
innodb_support_xa
已被弃用,将来版本会被移除。MySQL 5.7.10版本,InnoDB
XA事务的两阶段提交是默认支持的,不能设置禁用innodb_support_xa
。
InnoDB
清除其它相关事务的数据。READ COMMITTED
作者 REPEATABLE READ
级别,则需要额外的处理来重建旧数据。PAGE_MAX_TRX_ID
,或者某些记录被标记为已删除,InnoDB
可能需要使用聚簇索引来查询相应的记录。覆盖索引查询(使用二级索引即可获得所需的数据,而不需要访问表数据)
InnoDB
可以避免给只读事务赋transaction ID (TRX_ID
)。事务ID只对执行写操作,或者含锁读操作,如 SELECT ... FOR UPDATE
有用。去除不必要的事务ID,有助于减少每次读写操作必须访问的内部数据结构大小。
InnoDB
在一下情景能够识别只读操作:
START TRANSACTION READ ONLY
开始,这种情况下,数据变更操作会引发错误,事务仍会以只读性质运行:ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.
对于事务中的临时表可以进行任何操作。
autocommit
= on,并且事务只包含一个语句,且语句为没有使用FOR UPDATE
或者 LOCK IN SHARED MODE
的SELECT
语句。READ ONLY
选项开始。这样,对于读繁忙的应用,如报表应用,可以将一系列的查询语句综合到一个只读的事务中,或者在执行查询前设置 autocommit
= on,或者在应用中避免将变更操作和查询操作相互影响。.
可以考虑遵循以下优化指引:
InnoDB
写满redo log时,服务器会基于一个检查点(checkpoint)就会将日志中的变更内容写到磁盘。如果redo log 文件过小,那么就会引发服务器频繁的写盘。虽然之前,设置过大的redo log 会引起恢复时间的过长,但是现在,恢复机制已经在速度上有很大的优化,因此不用再考虑此因素。The size and number of redo log 文件的大小和数量可以使用: innodb_log_file_size
和 innodb_log_files_in_group
进行设置。
innodb_log_buffer_size
。innodb_log_write_ahead_size
变量以避免 “read-on-write”(就是当修改的字节不足一个洗系统block时,需要将整个block读进内存,修改对应的位置,然后再写进去;如果我们以block为单位来写入的话,直接完整覆盖写入即可)。这个配置定义了redo log的write-ahead块大小。设置innodb_log_write_ahead_size
的大小以匹配操作系统或者文件系统的缓存块大小。Read-on-write 的产生是因为在write-ahead 块大小和操作系统或者文件系统的缓存块大小不匹配的情况下,redo log 块无法完全的写入到操作系统,或者文件系统引起的。innodb_log_write_ahead_size
的值可以设置为InnoDB
日志文件块大小的倍数(2n)。最小的值为(512)。设置为最小值时Write-ahead不会发生。最大值为innodb_page_size
。如果设置的值大于innodb_page_size
,那么服务器会使用innodb_page_size
值。
innodb_log_write_ahead_size
值设置的太小,会导致read-on-write;设置过大,则会影响fsync
性能,因为一次需要些多个数据块。
快速插入通用指引:
SET autocommit
及 COMMIT
语句:SETautocommit
=0;
...SQLimport statements ...
COMMIT;
mysqldump 选项 --opt
(默认启用)会创建dump转储 文件,以执行快速数据导入,避免将所有的数据载入内存引发问题。即使不使用SET autocommit
和 COMMIT
。
UNIQUE
限制,可以在载入时暂时关闭比检查:SETunique_checks
=0;
...SQLimport statements ...
SET unique_checks
=1;
对于较大的表,此操作可以节省大量的磁盘I/O,因为InnoDB
可以使用它的 change buffer(change buffer的主要目的是将对二级索引的数据操作缓存下来,以此减少二级索引的随机IO,并达到操作合并的效果)来批量写二级索引记录。确保数据不包含重复键。
FOREIGN KEY
限制。可以再导入期间关闭此限制:SETforeign_key_checks
=0;
...SQLimport statements ...
SET foreign_key_checks
=1;
INSERTINTO
yourtable
VALUES(1,2),
(5,5),
...;
适用于任何类型表。
innodb_autoinc_lock_mode
= 2 (默认1,0:traditional;1:consecutive;2:interleaved)。InnoDB
表主键索引未聚簇索引(clustered index, 以主键的顺序访问会很快)。特别是对于无法完全载入缓存的大表。FTS_DOC_ID
,
类型BIGINT UNSIGNED NOT NULL
,,列上定义索引FTS_DOC_ID_INDEX
,如下:CREATETABLE
t1
(
FTS_DOC_ID
BIGINTunsigned
NOT
NULL
AUTO_INCREMENT,
title
varchar(255)NOT
NULL
DEFAULT
‘‘,
textmediumtext
NOT
NULL,
PRIMARYKEY
(`
FTS_DOC_ID
`)
)ENGINE=
InnoDB
DEFAULTCHARSET=
latin1
;
CREATEUNIQUE
INDEX
FTS_DOC_ID_INDEX
ont1
(FTS_DOC_ID
);
Note
在innodb存储引擎中,为了支持全文检索,必须有一个列与word进行映射,在innodb中这个列被命名为FTS_DOC_ID,其类型必须为BIGINT UNSIGNED NOT NULL,并且innodb存储引擎会在该列上加上一个名为FTS_DOC_ID_INDEX的唯一索引。上述操作由innodb存储引擎自己完成,用户也可以在创建表时手动添加,主要对应的约束条件。
常规的索引是文档到关键词的映射:文档——>关键词
倒排索引是关键词到文档的映射:关键词——>文档
全文索引通过关键字找到关键字所在文档,可以提高查询效率
表创建时添加FTS_DOC_ID
列,确保FTS_DOC_ID
列跟随全文索引列同步更新(FTS_DOC_ID
必须随着相应的 INSERT
或者 UPDATE
变更单调递增)。如果不添加FTS_DOC_ID
列,而让InnoDB
来管理DOC IDs,InnoDB
也会在执行CREATE FULLTEXT INDEX
时添加隐藏列FTS_DOC_ID
。这样,则需要进行额外的表重建过程,造成不必要的性能影响。
创建适当的索引以优化查询,通用指引如下:
NOT
NULL
。优化器以此可以更高的决定最优使用索引。
CREATE
, ALTER
,
及DROP
语句) 可以在线之行。TRUNCATE
TABLE
代替DELETE FROM
tbl_name
来清空表,外键限制可以使得TRUNCATE
语句如普通的DELETE
语句般操作。这种情景下,一系列如DROP
TABLE
及 CREATE
TABLE
语句会执行的很快。
如果数据库的设计及sql操作优化都遵循了最佳实践,数据库依然因为I/O负载而反应非常慢,那么就需要针对I/O进行专门的优化。可以通过Unix 的top
工具,或者Windows
的任务管理器来查看工作负载,如果低于70%,那么负载则主要在磁盘。
InnoDB
缓存中的数据访问不需要磁盘I/O,使用innodb_buffer_pool_size
设置。建议设置为系统内存的50 ~ 75%。
某些版本GNU/Linux 系统,使用fsync()
或者相关方法进行刷盘时,速度会非常慢。这时,如果影响到数据库性能,那么可以通过设置innodb_flush_method
= O_DSYNC
来变更刷盘策略。
InnoDB
在Linux系统上使用异步I/O 子系统(本地AIO)通过预读和写请求来执行数据文件读写。配置变量innodb_use_native_aio
默认启用。磁盘调度策略对本地
AIO印象比较大。通常建议设置为noop
或者
deadline。
Non-rotational 存储适用于随机读写;rotational存储相反适用于顺序读写。不同的存储设备对数据及日志的操作类型不同。
数据库随机读写类文件包括:file-per-table 和general tablespace数据文件, undo tablespace文件和temporary tablespace 文件。顺序读写类文件包括:InnoDB
system tablespace 文件(基于 doublewrite buffering and change buffering) 及日志文件( binary log 文件和redo log 文件等)。
使用non-rotational 存储时,需要对一下配置进行优化:
crc32
算法使用了一种更快的一致性检查算法,对于高速存储设备,推荐使用。
针对rotational存储设备优化。对于non-rotational设备或者混用情景,则需禁用。
默认的200设定对于低端non-rotational存储设备已经足够。其它,酌情设置。
默认2000 针对non-rotational 存储。
如果redo logs存储在non-rotational设备,可以开率禁用词选项来减少日志。
如果redo logs 存储在non-rotational 存储设备,设置此选项最大读写缓存。
设置此值以匹配磁盘internal sector size。早期的SSD设备为4KB,一些新版本的SSD能够支持到16KB。默认的额InnoDB
也大小为16KB。尽量是的数据库也大小和存储设备的块大小接近,减少无法一次写入磁盘的数据大小。
binary logs 存储在non-rotational 设备情况下,如果所有的表都有主键,那么可以将此变量设置为最小来减少日志。
Ensure that TRIM support is enabled for your operating system. It is typically enabled by default.
如果吞吐量会因为检测点操作而不间断的降低,那么可以开率增加 innodb_io_capacity
的值。值越大,数据库刷盘频率会增大,从而避免了因为backlog的操作带来的吞吐量的影响。
如果系统能够满足nnoDB
刷盘操作。可以考虑减小innodb_io_capacity
配置。通常需要将此变量尽量设置低一些。(SHOW
ENGINE INNODB STATUS
)
如果使用支持原子写的Fusion-io设备存储系统表空间文件(“ibdata files”)
,那么可以对doublewrite
buffer-related I/O进行相应的优化。这种情况下,会自动使用Fusion-io设备的原子写替代doublewrite
buffering (innodb_doublewrite
)进行数据的读写。这种特性只支持Fusion-io硬件设备及Fusion-io
NVMFS Linux应用。可以通过变量innodb_flush_method
=
O_DIRECT
进行配置。
Note
设置是全局性的,影响所有设备上的数据读写。
使用 InnoDB
表压缩特性时,重新压缩的图片数据页,如果数据有变化,则会写入redo log。配置变量innodb_log_compressed_pages
默认启用,防止数据库恢复期间,因为zlib算法的变化引发数据库崩溃。如果可以确认zlib版本不会发生变化,那么可以关闭innodb_log_compressed_pages
变量来减少重压缩产生的redo
log 负载。
标签:查询 拷贝 不用 创建 系统表 架构 工作 建议 变化
原文地址:https://www.cnblogs.com/niejunlei/p/10320303.html