如何处理MySQL中的大表?

时间:2010-05-24 18:09:51

标签: mysql database optimization

我有一个用于存储有关这些项目的项目和属性的数据库。属性数是可扩展的,因此有一个连接表来存储与项值相关联的每个属性。

CREATE TABLE `item_property` (
    `property_id` int(11) NOT NULL,
    `item_id` int(11) NOT NULL,
    `value` double NOT NULL,
    PRIMARY KEY  (`property_id`,`item_id`),
    KEY `item_id` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

这个数据库有两个目标:存储(具有第一优先级,必须非常快,我想在几秒钟内执行许多插入(数百)),检索数据(使用item_id和property_id选择)(这是一个第二优先级,它可能更慢但不会太多,因为这会破坏我对数据库的使用。

目前这个表存有1.6亿条目,简单计数可能需要2分钟......插入速度不够快,无法使用。

我正在使用Zend_Db访问我的数据,如果您建议我开发任何PHP副作用,我会非常高兴。

7 个答案:

答案 0 :(得分:10)

如果由于某些原因无法使用不同的数据库管理系统或通过群集进行分区,那么仍然可以做三件主要的事情来从根本上提高您的性能(并且它们可以正常工作)当然也与集群结合):

  • 设置MyISAM存储引擎
  • 使用“LOAD DATA INFILE filename INTO TABLE tablename”
  • 将数据拆分为多个表格

就是这样。只有在您对细节感兴趣时才能阅读其余内容:)

还在看吗?那么,好吧,MyISAM是角石,因为它是迄今为止最快的引擎。您应该使用常规SQL语句插入数据行,而不是定期将它们批量添加到文件insert that file中(根据需要经常进行,但很少应用程序允许这样做)。这样,您可以按每分钟一百万行的顺序插入。

接下来会限制你的是键/索引。当那些不适合你的记忆时(因为它们只是变大)你会在插入和查询中遇到巨大的减速。这就是为什么你将数据分成几个表,所有表都使用相同的模式。每个表应该尽可能大,一次加载一个表时不会填满你的记忆。确切的大小取决于您的机器和索引当然,但应该介于5到5千万行/表之间。如果你只是测量插入一大堆一行又一行的时间,那么你会发现这一点,寻找它显着减速的那一刻。当您知道限制时,每次最后一个表接近该限制时,都会动态创建一个新表。

多表解决方案的结果是,当您需要某些数据时,您将不得不查询所有表格而不是单个表格,这会使您的查询速度降低一些(但如果您“仅” “有十亿左右的行。”显然,这里也有优化。如果有一些基本的东西可以用来分隔数据(比如日期,客户端或其他东西),你可以使用一些结构化的模式将它分成不同的表,这样可以让你知道某些类型的数据在哪里甚至不查询表。使用该知识仅查询可能包含所请求数据的表等。

如果您需要更多调整,请按照Eineki和oedo的建议去partitioning

另外,所以你知道所有这些都不是疯狂的猜测:我现在正在对我们自己的数据进行一些这样的可伸缩性测试,这种方法对我们来说是奇迹。我们每天都要插入数千万行,查询大约需要100毫秒。

答案 1 :(得分:0)

首先不要使用InnoDb,因为您似乎不需要MyISAM的主要功能(锁定,事务等...)。 所以使用MyISAM,它已经会有所不同。 然后,如果仍然不够快,请进入一些索引,但你应该已经看到了根本的差异。

答案 2 :(得分:0)

哇,这是一张相当大的表:)

如果您需要快速存储,可以批量插入并使用单个多个INSERT语句插入它们。但是这肯定需要额外的客户端(php)代码,对不起!

INSERT INTO `table` (`col1`, `col2`) VALUES (1, 2), (3, 4), (5, 6)...

还会禁用您不需要的任何索引,因为索引会降低插入命令的速度。

或者您可以查看对表格进行分区:linky

答案 3 :(得分:0)

查看内存缓存以了解它的应用位置。还要研究水平分区以保持表大小/索引更小。

答案 4 :(得分:0)

首先:一个有16亿条目的表似乎有点太大了。我在一些非常繁重的负载系统上工作,即使是跟踪所有操作的记录表也不会在多年内变得如此重要。如果可能,请考虑一下,如果您能找到更优化的存储方法。因为我不知道你的数据库结构,所以不能提供更多建议,但我确信会有足够的优化空间。 16亿条目太大了。

关于表现的一些事情:

如果您不需要参考完整性检查(这不太可能),您可以切换到MyISAM存储引擎。它有点快,但缺乏完整的ckecks和交易。

除此之外,还需要更多信息。

答案 5 :(得分:0)

您是否考虑过partitioning表的选项?

答案 6 :(得分:-2)

要记住的一件重要事情是MySQL的默认安装没有配置为像这样繁重的工作。确保您的工作量有tuned it