【发布时间】:2010-12-10 06:50:55
【问题描述】:
我终于被说服将我的小表放在一个大表中,但是对于 MySQL 表来说到底多大才算太大?
我有一个包含 18 个字段的表格。有些是TEXT,有些是短的VARCHAR(16),有些是更长的VARCHAR(100)。
现在我们每天大约有 200,000 行,这将是每月 600 万+。多大才算太大?有多少字段或只有行是否重要?
【问题讨论】:
我终于被说服将我的小表放在一个大表中,但是对于 MySQL 表来说到底多大才算太大?
我有一个包含 18 个字段的表格。有些是TEXT,有些是短的VARCHAR(16),有些是更长的VARCHAR(100)。
现在我们每天大约有 200,000 行,这将是每月 600 万+。多大才算太大?有多少字段或只有行是否重要?
【问题讨论】:
对于“多大才算太大”这个问题没有一个很好的通用解决方案 - 此类问题通常取决于您对数据的处理方式以及您对性能的考虑。
表格大小有一些基本限制。您不能有超过 1000 列。您的记录不能大于 8k。这些限制因数据库引擎而异。 (这里是 InnoDB 的。)
听起来您已经将几个不同的数据集合并到一个表中。您可能有一些字段可以告诉您此记录所属的数据集,以及一些数据字段和一些时间戳信息。这不是一个非常广泛的记录(除非您记录每个请求的所有输入参数。)您的主要问题将是 选择性。以有意义的方式索引该表将是一个挑战。如果您的公共字段可以有足够的选择性,您可以使用它们来获取您想要的记录而无需查阅表格,那将是一个巨大的优势。 (参见表扫描)
对于每天这么多的记录(基本上,全天每秒两次,我假设您有一个高峰期,它要高得多),您还需要确保您专门查看优化关于提高插入速度。作为一般规则,更多的索引 = 更慢的插入。如果可以,请考虑将过时的记录完全归档到另一个表中。在以前的工作场所,我们使用了上个月、前三个月、前六个月的存档策略,每个都在单独的表格中。另一个想法是删除旧记录。许多环境根本不需要超过特定日期的信息。保留三个月前的日志记录通常过于昂贵。
最后,不要忽视桌子的物理存储。您的记录越薄,读取(或就此而言,插入)记录所需的物理 IO 就越少。您可以将索引存储在单独的物理硬盘驱动器上。如果存储压缩表的记录中有大量冗余数据,实际上可能会提高速度。如果您有一点现金可以烧掉,请考虑一个好的 RAID 阵列对数据条带化的价值。
所以,回答您的基本问题:这是很多记录,但仔细调整调整,这不是问题。
【讨论】:
我有一个大约 9800 万行的表,并且整天都在进行插入/删除。我们将记录保存 90 天...我预计本月该表的行数约为 1 亿行。就我个人而言,我会以不同的方式设计数据库架构,但它是购买的,我们需要保持原样,以免使任何供应商支持失效。
我们正在使用 mysql 复制 (MASTER-MASTER) 并在一个上执行插入/删除并在另一个上执行查询。这确实有助于提高性能,因为在我们更改为使用复制之前,删除会锁定表并阻止查询。
使用此实现,我们没有遇到任何性能问题。
我还每周执行一次表格优化...
【讨论】:
我认为这取决于,基本上。您使用的是哪个版本的 MySQL,什么操作系统,您使用的是 MyISAM 还是 innoDB 表?它也是different on 32-bit and 64-bit,并且因您的日志记录设置而异。 MySQL manual 说:
有效的最大表大小 MySQL数据库通常确定 受操作系统约束 文件大小,不是 MySQL 内部的 限制
该页面上还有更多关于这些限制的详细信息。
【讨论】:
在单个表中放置多少列的选择还取决于所表示的数据类型以及您对规范化的关注程度。有些关系可以很容易地用一张表来表示;其他需要在多个较小的表中完成,尤其是当您在数据集中混合了一对一、一对多和多对多类型关系时。
【讨论】:
不是确切问题的答案...
为什么说服您将较小的桌子放在一张大桌子上? 您所做的称为“垂直分区”,实际上可能非常有用,具体取决于您的情况。由于有许多大的 TEXT 或 BLOB 字段,垂直分区可以将更多查询的数据物理地放在一起并更快地访问。
见:http://en.wikipedia.org/wiki/Partition_(database)
垂直分区涉及创建具有较少列的表并使用额外的表来存储剩余的列。规范化还涉及跨表的列拆分,但垂直分区超出了这一范围,即使已经规范化了也会对列进行分区。也可以使用不同的物理存储来实现垂直分区;例如,在不同的设备上存储不经常使用或非常宽的列是一种垂直分区方法。显式或隐式完成,这种类型的分区称为“行拆分”(行按列拆分)。垂直分区的一种常见形式是从表中的(快速查找)静态数据中拆分(查找慢)动态数据,其中动态数据不像静态数据那样经常使用。在两个新创建的表之间创建视图会恢复原始表,但会降低性能,但是在访问静态数据时性能会提高,例如用于统计分析
另见:http://dev.mysql.com/tech-resources/articles/performance-partitioning.html
【讨论】:
考虑您需要对桌子做什么。如果表格纯粹是为了实现,你永远不需要改变它的结构或任何东西。如果你需要它来进行数据挖掘,你会期望改变它的结构。例如,现在尝试在其副本上执行更改表。一旦达到临时表变大以存储在内存中的水平,预计此函数的性能会下降。
我也遇到过同样的情况,数据量太大,无法修改数据库的结构。 现在你应该做的是让某人在机器(即 EC2 实例)上创建一个数据库,其中包含你期望在两年内拥有的数据量。只需让他们以相同的表格格式创建虚假数据。尝试使用此表并确定性能是否可以接受。如果不可接受,您需要尽快进行更改。
如果我是你,我会考虑测试 Greenplum 或(如果你没有钱花,GridSQL)。两者均基于 PostgreSQL,并使用多台计算机协同工作。
【讨论】: