我有一张表已达到近300万条记录。虽然我很欣赏这个数量可能不会被认为比RDBMS大,但我注意到处理这个表的操作减慢了。我觉得我可以优化或重新构建它。
这是PocketBracket March Madness App数据库的一部分。本质上,该表存储一对多关系的元数据(Brackets有许多Bracket Picks)。扭曲是表上的需求有时会有所不同。例如,表的执行时间很短(两周)。但在今年剩下的时间里,它主要是阅读。此外,绝大多数记录都没有被访问。
以下是当前结构的屏幕截图:
有了这个,我有一些想法:
我很感激你的指示。最后,我对代码更改很好,我只是想确保我在正确的方向上重新构建。
答案 0 :(得分:1)
基于this oracle blog article(及附白皮书),我假设从MyISAM迁移到InnoDB可以解决您的问题。只是出于好奇他们的基准硬件配置:
- 4个插槽,总共48个内核,4个12核AMD Opteron 6172“Magny-Cours”2.1GHz CPU。 (注意:36个内核被分配给MySQL和 剩余的12个Sysbench流程)。
- 64 GB DDR3 RAM
- 2 x Intel X25E SSD驱动器
但更重要的是读写比较:
如下图所示,InnoDB的吞吐量提高了35倍 MyISAM可实现85%-90%的可扩展性,从6核到36核。 超过30个核心,可扩展性曲线开始变得扁平化 热的互斥体数量增长,但性能仍然继续 增加。
和只读比较:
InnoDB的吞吐量比MyISAM提高了4.6倍,同时实现了 90% - 95%的可扩展性,从6核到36核。超过30核,可扩展性 当服务器再次被一些热点饱和时,它会变平 互斥。
所有引用均来自Oracle 2011年1月的文章及其版权:版权所有©2011,Oracle和/或其关联公司。保留所有权利。
他们在InnoDB和MyISAM中提到的唯一缺点是:
Here's an article调整InnoDB。
您应该{My}选择MyISAM引擎和InnoDB上的查询(确保正确设置FOREIGN KEY
)。你可以使用这样的基准:
DO BENCHMARK( 100, (SELECT games.someField
FROM brackets
INNER JOIN relation_table ON relation_table.bracketID = brackets.id
INNER JOIN games ON games.id = relation_table.gameID
LIMIT 1
));
如果迁移到InnoDB无济于事我担心最好的解决方案是迁移代码并将旧结果存储在其他地方(增加数据库的内存限制可能会大大影响其性能)。
无论如何,请将结果发布到评论中,我很好奇这个
答案 1 :(得分:1)
在疯狂使用分区,分片,非规范化等“优化”之前......这将引入许多其他问题,我首先会尝试检测导致速度减慢的原因。
举个例子,我有一个大约有3000万条记录的表,我做了很多插入,每秒读取,我可以在不到300毫秒的时间内获得大约2000条记录的查询结果。 (仍然可能会有所改善)
此外,请记住,当您可以在多个磁盘之间拆分文件时,分区会产生敏感,因此您可以增加整体I / O.换句话说,你需要为每个磁盘分配一个文件才能获得良好的性能。
首先,获得更多信息非常重要
可能只是表只是碎片化而且mysql配置需要更多调整。 首先,你应该像Vyktor建议的那样切换到innodb,然后你还要将innod db buffer配置为更高的值。默认值太低。 这是我的配置文件的一个例子。请记住,参数是针对我的数据类型,查询和服务器规范而调整的。另外我使用的是名为percona的MySQL变体,它可以帮助你,因为它被证明更快。在网站上你可以找到一些基准。
innodb_file_per_table
innodb_file_format=barracuda
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_size = 3GB
query_cache_size = 98304
innodb_log_file_size = 10485760
innodb_log_buffer_size = 3145728
我也会尝试运行mysqlcheck。 警告!!! 它锁定了桌子!
如果您需要有关mysql调优的更多信息,这是一个很棒的blog
答案 2 :(得分:0)
好的,分区具有以下优点。
以下是从mysql文档中摘录的一些摘录。
我还在答案的最后提供了关于不同数据库的表分区的链接列表。有些人可能还想了解SHARDING
http://en.wikipedia.org/wiki/Shard_(database_architecture)
但是,因为每一项技术都应该小心对待分区,而不仅仅是遵循 盲目地建议它有它的缺点,可能我发现它需要它 正如Tom Kyte在他的oracle博客中所说的那样,很多互动和可管理性受到影响:
are your tables getting larger then you feel comfortable managing? eg: it might take longer to
restore a 100gig tablespace than 1-10 gig tablespace (and the other 90gig of data is online whilst
doing this)
优点:
分区可以在一个表中存储比在单个磁盘或文件系统分区上保存的数据更多的数据。
通过删除仅包含该数据的分区(或多个分区),通常可以轻松地从分区表中删除失去其实用性的数据。相反,在某些情况下,通过添加一个或多个新分区来特别存储该数据,可以极大地促进添加新数据的过程。
由于满足给定WHERE子句的数据只能存储在一个或多个分区上,因此可以大大优化某些查询,这些分区会自动从搜索中排除任何剩余的分区。由于在创建分区表后可以更改分区,因此可以重新组织数据以增强在首次设置分区方案时可能不常使用的频繁查询。这种排除不匹配分区(以及它们包含的任何行)的能力通常被称为分区修剪,并在MySQL 5中实现
通常与分区相关的其他好处包括以下列表中的那些好处。这些功能目前尚未在MySQL Partitioning中实现,但在我们的优先级列表中占据很高的位置。
可以轻松地并行化涉及SUM()和COUNT()等聚合函数的查询。这种查询的一个简单示例可能是SELECT salesperson_id,COUNT(orders)as order_total FROM sales GROUP BY salesperson_id;。通过“并行化”,我们的意思是可以在每个分区上同时运行查询,并且仅通过对所有分区获得的结果求和来获得最终结果。
通过在多个磁盘上传播数据来实现更高的查询吞吐量。
链接
http://dev.mysql.com/doc/refman/5.1/en/partitioning.html
http://forums.mysql.com/list.php?106
http://www.slideshare.net/datacharmer/mysql-partitions-tutorial
http://msdn.microsoft.com/en-us/library/ms345146(v=sql.90).aspx
http://msdn.microsoft.com/en-us/library/ms190787.aspx
http://docs.oracle.com/cd/B10501_01/server.920/a96524/c12parti.htm
http://docs.oracle.com/cd/B28359_01/server.111/b32024/partition.htm
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:728425384831
http://www.postgresql.org/docs/9.1/static/ddl-partitioning.html
希望它有助于升技