Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL中的解耦表在多大程度上提高了性能?_Mysql_Database_Performance_Database Design_Database Performance - Fatal编程技术网

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

我正在设计数据库,以便在MySQL中存储一些博客文章。我最近遇到了这样一条建议,当您:

  • 定期查询的表(例如博客文章列表),但
  • 该表中的一列包含大量不会定期访问的数据(博客内容)
  • 然后,如果将内容存储在单独的表中,性能会更好,因此,当生成列表时,速度会更快

    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,如果内存不重要,则扫描覆盖索引可能是拆分表的替代方法。如果您没有使用覆盖索引来满足搜索,那么您只是在扫描冗余数据时使用了大量内存。现在,如果你说的是避免表扫描的索引,是的,我在回答中已经提到了这一点。当然,有些查询没有完全利用索引(以限制结果集),需要进行一些扫描。