MySQL中的解耦表在多大程度上提高了性能?
我正在设计数据库,以便在MySQL中存储一些博客文章。我最近遇到了这样一条建议,当您:MySQL中的解耦表在多大程度上提高了性能?,mysql,database,performance,database-design,database-performance,Mysql,Database,Performance,Database Design,Database Performance,我正在设计数据库,以便在MySQL中存储一些博客文章。我最近遇到了这样一条建议,当您: 定期查询的表(例如博客文章列表),但 该表中的一列包含大量不会定期访问的数据(博客内容) 然后,如果将内容存储在单独的表中,性能会更好,因此,当生成列表时,速度会更快 CREATE TABLE article ( id INT(10) UNSIGNED, title VARCHAR(40), author_id INT(10) UNIGNED, created DATETIME
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
);
即使列不是查询的一部分,这是否也会影响性能:
SELECT id, title FROM article WHERE author_id=33 ORDER BY created DESC LIMIT 5
在多大程度上它会成为性能问题?(几十万?几百万?对你所有的问题都是肯定的 当不总是需要
文本
(或BLOB
等)时,“垂直分区”(构建“并行表”)非常有用
当您不需要文本时
,由于该表中的体积较小,因此它的性能更好
当您确实需要文本
时,您可能只获取一行(或很少)行,因此将联接到额外表中的成本不会太高
我有两个数据库,每一个都有20万行,像这样分开。两者的规模都很好。我预计数百万,甚至数十亿都不会有问题。(好吧,“数十亿”有很多问题,但垂直分区是解决方案之一。)
您的示例SELECT
需要一个“复合”索引(author\u id,created)来进行缩放。但这与垂直分区无关 对于MySQL 5.5及更高版本,InnoDB存储引擎支持。为了使用InnoDB的Barracuda文件格式,您必须在每个表空间中使用一个文件,或者使用一个通用表空间(单个文件“系统”InnoDB表空间不支持Barracuda)
在梭鱼(羚羊)之前。在这种情况下,即使没有引用文本列,也会增加聚集索引(叶节点)中每一行的大小。这降低了对其他非文本列的表扫描速度,因为每页上适合的页面较少(平均要扫描更多页面以查找所需内容),但在扫描文本列时(不管怎样,前768个字节)的性能有所提高。你经常扫描桌子吗?希望您能够使用索引来避免表扫描
索引和键搜索在只包含键的内部节点上完成。对于聚集索引,这只是主键,因此聚集索引搜索不受叶节点中数据量的影响(但受主键大小的影响)
对于InnoDB的Barracuda文件系统,整个文本列存储在溢出页中(可以压缩)。它的任何部分都不会存储在聚集索引(叶节点)中。因此,如果您使用的是Barracuda文件系统,那么让MySQL为您进行分离,并将文本列放在同一个表中。在这种情况下,您将一无所获,因为MYSQL已经将文本列放在其他地方,并且不会影响对非文本列的扫描
如果你使用羚羊,如果你经常扫描非文本列,你可能会考虑拆分它(无论如何你应该避免),而且很少引用文本列。将其拆分为两个表,要读取整个记录,您现在必须在两个聚集索引上进行搜索,这是一个索引的两倍
我还看到,在MySQL限制InnoDB缓冲区空间的RAM的系统上,想要将其与Antelope拆分,而您很少引用文本列。如果包含非文本列的叶节点较小,则它们更有可能留在内存中。记住TEXT
默认情况下非常小。您可能希望LONGTEXT
更安全。除非您执行SELECT*
操作,否则TEXT
列的开销通常是适中的。马库斯解释道:@Marcus Adams的5.5条评论是有效的;我没有可供比较的直接经验。(我的桌子是5.1天建成的。)当然。我已经构建了一个与此完全相同的大规模模式,因为它也可以追溯到那个时代,但现在我只是将它们内联,以避免造成混乱。(事实上,我会使用Postgres,但这是另一个问题。)关于MySQL 5.5中的重要更改,我要用一句话来反驳——所有索引都基于BTrees,而不是二进制搜索。一百万行的BTree中可能有3个级别;即使行大小更改768字节,该深度也不太可能增长/收缩。我建议点查询的搜索时间几乎相同。谢谢@MarcusAdams的回答,我想我需要研究梭鱼、羚羊、b-树、叶节点、簇索引等,以便我完全理解你的回答!在非文本属性上使用覆盖索引不会有同样的好处吗?(当然,假设不经常进行完整表扫描)@symcbean,如果内存不重要,则扫描覆盖索引可能是拆分表的替代方法。如果您没有使用覆盖索引来满足搜索,那么您只是在扫描冗余数据时使用了大量内存。现在,如果你说的是避免表扫描的索引,是的,我在回答中已经提到了这一点。当然,有些查询没有完全利用索引(以限制结果集),需要进行一些扫描。