AsT*_*TeR 10 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;
Run Code Online (Sandbox Code Playgroud)
这个数据库有两个目标:存储(具有第一优先级并且必须非常快,我想在几秒钟内执行许多插入(数百)),检索数据(使用item_id和property_id选择)(这是第二优先级,它可以更慢但不会太多,因为这会破坏我对DB的使用).
目前这个表存储了16亿个条目,简单计数最多可能需要2分钟...插入速度不够快,无法使用.
我正在使用Zend_Db来访问我的数据,如果你不建议我开发任何PHP副作用,我会非常高兴.
Jak*_*kob 10
如果由于某些原因无法使用不同的数据库管理系统或通过群集进行分区,那么仍然可以通过三个主要方法来彻底改善您的性能(当然,它们也可以与群集一起使用):
而已.如果您对细节感兴趣,请阅读其余内容:)
还在看?那么,好吧,MyISAM是角石,因为它是迄今为止最快的引擎.您不应该使用常规SQL语句插入数据行,而应将它们在文件中批处理并定期插入该文件(根据需要经常插入,但很少应用程序允许这样做最好).这样,您可以按每分钟一百万行的顺序插入.
接下来会限制你的是键/索引.当那些不适合你的记忆时(因为它们只是为了大)你会在插入和查询中遇到巨大的减速.这就是为什么你将数据分成几个表,所有表都使用相同的模式.每个表应该尽可能大,一次加载一个表时不会填满你的记忆.确切的大小取决于您的机器和索引当然,但应该介于5到5千万行/表之间.如果你只是测量插入一大堆一行又一行的时间,那么你会发现这一点,寻找它显着减速的那一刻.当您知道限制时,每次最后一个表接近该限制时,都会动态创建一个新表.
多表解决方案的结果是,当您需要一些数据时,您将不得不查询所有表而不是单个表,这会使您的查询减慢一点(但如果您"只"拥有一个数据,则不会太多十亿左右的行).显然,这里也有优化.如果有一些基本的东西可以用来分隔数据(比如日期,客户端或其他东西),你可以使用一些结构化的模式将它拆分成不同的表,这样可以让你知道某些类型的数据在哪里甚至没有查询表.使用该知识仅查询可能包含所请求数据的表等.
如果您需要更多调整,请按照Eineki和oedo的建议进行分区.
另外,所以你知道所有这些都不是疯狂的猜测:我现在正在对我们自己的数据做一些这样的可扩展性测试,这种方法对我们来说是奇迹.我们每天都要插入数千万行,查询大约需要100毫秒.