MySQL中的解耦表能提高多少性能?

day*_*oli 4 mysql database performance database-design database-performance

我正在设计数据库以在MySQL中存储一些博客文章.我最近碰到了这个答案,建议你什么时候:

  1. 将定期查询的表格(例如博客文章列表),但是
  2. 该表中的一列包含大量不经常访问的数据(博客内容)

然后,如果将内容存储在单独的表中,那么性能会更好,所以当您生成列表时,它会更快.

CREATE TABLE article (
    id INT(10) UNSIGNED,
    title VARCHAR(40),
    author_id INT(10) UNIGNED,
    created DATETIME,
    modified DATETIME
);

CREATE TABLE article_text (
    id INT(10) UNSIGNED,
    body TEXT
);
Run Code Online (Sandbox Code Playgroud)

即使该列不是查询的一部分,这是否会影响性能:

SELECT id, title FROM article WHERE author_id=33 ORDER BY created DESC LIMIT 5
Run Code Online (Sandbox Code Playgroud)

它在多大程度上成为性能问题?(几百,几万??百万?)

Mar*_*ams 7

使用MySQL 5.5及更高版本,InnoDB存储引擎支持Barracuda文件格式.为了使用InnoDB的Barracuda文件格式,您必须使用每表文件表空间,或使用通用表空间(单文件"系统"InnoDB表空间不支持Barracuda).

在Barracuda(Antelope)之前,MySQL总是至少存储集群(主键)索引中TEXT列的前768个字节.在这种情况下,具有TEXT列,即使没有引用它,也会增加聚簇索引(叶节点)中每行的大小.由于较少的页面适合每个页面(平均扫描更多页面以查找您正在查找的内容),因此在其他非TEXT列上的表扫描速度变慢,但在扫描TEXT列时仍然提高了性能(无论如何,前768个字节) .你在做很多桌面扫描吗?希望您能够使用索引来避免表扫描.

索引是b树,密钥搜索在内部节点完成,内部节点只包含密钥.对于聚簇索引,这只是主键,因此聚簇索引搜索不受叶节点中数据量的影响(但受主键大小影响).

使用InnoDB的Barracuda文件系统,整个TEXT列存储在溢出页面中(可以压缩).它的任何部分都不存储在聚簇索引(叶节点)中.因此,如果您正在使用Barracuda文件系统,请让MySQL为您进行分离,并将TEXT列放在同一个表中.在这种情况下你没有获得任何东西,因为MYSQL已经将TEXT列放在其他地方并且不影响扫描非TEXT列.

如果您使用的是Antelope,如果您经常扫描非TEXT列(无论如何应该避免),您可能会考虑拆分它,并且您很少引用TEXT列.将它拆分为两个表来读取整个记录,您现在必须对两个聚簇索引进行搜索,这两个索引的价格是一个索引的两倍.

我还可以看到想要在一个系统上将它与Antelope分开,在这个系统中,MySQL的InnoDB缓冲区空间有限,而你很少引用TEXT列.包含非TEXT列的叶节点如果较小则更有可能留在内存中.