我有一个很大的桌子,我对它进行了非常简单的查询,例如ID查找。
由于表行的增加,查询随着时间的推移而变慢。
我每秒执行约300个查询,这使我的脚本运行缓慢,内存达到99%(内存小于数据库的大小)
我想对表进行分区和再划分以获得最大性能,这是我的表(喜欢它的30个表),请添加代码,因为我对分区非常陌生,并且了解的不多。
选择查询仅是用于id查找和简单插入的where子句。
我想将RAM升级到比DB更大的大小,但是我想避免它,我不知道它是否能更好地解决分区问题。
CREATE TABLE `books` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`picture` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`url` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`created` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `url` (`url`(333)),
INDEX `name` (`name`)
)
COLLATE='utf8_unicode_ci'
ENGINE=MyISAM
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=937
这是我的一些查询示例:
SELECT id FROM books WHERE url = 'blabla';
INSERT INTO user_books SET book_id = '3', user_id = '10';
每个查询大约需要0.05-0.2秒
我在每个表中大约有5-10百万行。
DB大小为10GB,我考虑过将RAM升级到16GB
最佳答案
如果您只想尝试添加分区,建议您按键使用partition。这实际上将只是使用内部哈希函数对表进行分区,该哈希函数将应用于分区指定的列。
在您的情况下,查询似乎使用最多的id
,并且由于这是主键,因此语法非常简单:
CREATE TABLE `books` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(200) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`picture` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`url` VARCHAR(500) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`created` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `url` (`url`(333)),
INDEX `name` (`name`)
)
PARTITION BY KEY()
PARTITIONS 8;
COLLATE='utf8_unicode_ci'
ENGINE=MyISAM
ROW_FORMAT=DEFAULT
AUTO_INCREMENT=937
上面将创建8个分区。由于我没有指定任何要与partitioning子句一起使用的列,因此MySQL默认使用主键,这对您来说很好。
假设
id
列中使用的整数值具有合理的平衡分布,则每个分区约为1.25 GB。现在,对特定ID进行查询时应该只从一个分区中选择数据,这将加快访问速度。您可以在此处参考MySQL文档:http://dev.mysql.com/doc/refman/5.5/en/partitioning-key.html
不用说,id是主键,因此它应该已经相当不错了。我不确定还有更多警告可能适用于MyISAM的索引和分区。我主要使用InnoDb,而这至少是要使用InnoDb来提高查询性能。
关于mysql - 通过主键和2个索引对mysql表进行分区和子分区以提高性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7097064/