2011-04-21 83 views
-2

我有一个大的大表,表的大小是GB的大约130 GB。数据每天都在表格中倾倒。优化MySQL表的方法

我想优化桌子......任何人都可以向我建议我该怎么做呢?

任何输入将是一个很大的帮助。

+5

删除记录的一半?说真的,如果你想要一个认真的回应,我认为你需要添加更多的信息。 – 2011-04-21 08:56:28

+1

@DBA向我们展示了'create table'语句以及一些您想要加速的查询。 – Johan 2011-04-21 09:02:50

+0

感谢您的快速反应..佩卡和约翰。 @皮卡 - 事实上,我不能删除任何东西,因为我需要的数据。 @Johan - 数据非常多,我甚至无法在该表中找到多少行。但其数十亿美元......该表已在InnoDB存储引擎中创建。表中有6个索引,其中一个索引是复合索引。 – 2011-04-21 09:06:21

回答

4

这取决于你如何试图优化它。

对于查询速度,包括多列索引在内的适当索引将是一个非常好的开始。做所有的查询解释,看看什么花了这么多时间。优化读取数据以存储它而不是重新查询的代码。

如果旧数据不太重要或者您的数据太多,您可以按年,月,周或日轮换表格。这样数据写入总是到一个非常小的表格。较旧的表格都是过时的(即tablefoo_2011_04),因此您有积压。

如果您尝试在同一个表中优化大小,请确保您使用的是适当的类型。如果您获得可变长度的字符串,请使用varchar而不是静态大小的数据。不要为状态指示器使用字符串,请在第二查找表中使用enum或int。

服务器应该有很多内存,所以它不会一直在磁盘上。

你也可以看看使用缓存层,如memcached。

有关实际问题的详细信息,您的情况以及要优化的内容将对您有所帮助。

+0

嗨埃文,谢谢scuh详细的解释。那么,是的旧数据很重要,但我可以将它与当前表分开。并将其存储在一年的表格中。但仍然一年有很多数据....有地方索引。在接近一百万条记录的一天内插入。现在修改表格设计是个好主意..不会破坏数据吗? – 2011-04-21 09:16:23

+0

这取决于您所做的更改。对于任何类型的表格修改,您都应该首先进行备份。如果一年太长,如果需要的话,你可以去月表甚至日表。最安全的做法是创建一个正确类型的新列。然后更新列以便新列等于原始列。然后验证数据是否正确。然后删除原始列。你可以写出你的更新以适当的方式转换数据。 – evan 2011-04-21 18:29:19

0

您应该向我们展示您的SHOW CREATE TABLE表名输出,以便我们可以看到列,索引等。

从一切的一瞥,似乎MySQL的partitioning是你需要实现,以进一步提高性能。

0

一些可能的策略。

如果数据集太大,可能会冗余地存储某些信息:如果某些记录的访问次数比其他记录更频繁,请保留缓存表,以使信息非规范化(或者限制连接数或创建表更少的列,所以你有一个精益表保持记忆在任何时候),或总结快速查找总结。

汇总表可以通过定期生成汇总表或通过使用触发器保持同步,或者甚至可以通过在最近一天的缓存表中结合以计算实际汇总,以及对历史数据的总结......将为您提供完整的精确度,同时不需要阅读完整的索引。测试以查看在您的情况下提供最佳性能的内容。

按句点拆分表格当然是一种选择。这就像分区,但Mayflower Blog建议自己做,因为MySQL的实现似乎有一定的局限性。

此外:如果这些历史表中的数据永远不会改变,并且您希望减少空间,则可以使用myisampack。支持索引(您必须重新编译)并报告性能增益,但是我怀疑读取单个行时会增加速度,但在大量读取时性能会下降(因为很多行需要拆包)。

最后:你可以从历史数据中思考你需要什么。它是否需要与最近的条目完全相同的信息,或者是否存在不再重要的事情?例如,我可以想象如果你有一个访问日志,它存储了各种信息,如ip,referal url,请求的url,用户代理......也许在5年的时间里,用户代理根本就不感兴趣,将一个页面+ css + javascript +图像的一个ip的所有请求合并为一个条目(可能对于精确文件具有不同的多对一表格)是很好的,并且referal url只需要一些发生并且可以从确切的时间或ip解耦。

2

如果您的表是一种记录表,可以有几种优化策略。

(1)仅存储基本数据。

  • 如果没有必要的 - 可为空 - 在它的列和它们不被用于聚集或分析,并将其存储到其他表。保持主桌小一点。例如:
  • 例)不要存储原始的HTTP_USER_AGENT字符串。预处理代理字符串并存储您想要查看的较小数据。

(2)将表格设置为固定格式。

  • 对于几乎固定长度的字符串,请使用CHAR,然后使用VARCHAR。这将有助于加快SELECT查询速度。
  • 例)IP VARCHAR(15)=> IP CHAR(15)

(3)总结旧数据,并将它们转储到其它表周期性。

  • 如果您不需要每天检查整个数据,请将其分为周期性表格(年/月/日)和商店汇总旧数据。
  • 例)Table_2011_11/Table_2011_11_28

(4)不要使用太多的索引大表。

  • 索引过多会导致插入查询的负担过重。

(5)使用ARCHIVE引擎。

0

不要忘记考虑存储数据的介质的速度。我认为你可以使用raid盘来加速访问,或者将表存储在RAM中,但是在130GB下可能是一个挑战!然后考虑处理器。我意识到这不是对你的问题的直接回答,但它可能有助于实现你的目标。

0

您仍然可以尝试使用表空间进行分区或按照@Evan的建议进行“每个表的周期”结构。

如果您的全文搜索失败可能应该去Sphinx/Lucene/Solr。外部搜索引擎绝对可以帮助你获得更快的速度。

如果我们在谈论表结构时,应该尽可能使用最小的数据类型。 如果optimize table太慢,对于真正的大表来说是真的,你可以备份这张表并将其恢复。在这种情况下,您需要获得一些停机时间。

作为底线: 如果您的全文搜索问题比应用任何表更改之前尝试使用外部搜索引擎。