我有一张非常大的桌子,我就像id查找一样对它进行非常简单的查询。 由于表行的增加,查询随时间变慢。 我在第二次执行大约300次查询,这使我的脚本运行缓慢,我的内存达到99%(内存低于数据库的大小) 我想对表进行分区和子分区以获得最佳性能,这是我的表(在30个表中就像它一样),请添加一个代码,因为我对分区很新,并且不太了解。 select查询只是id查找和简单插入子句的where子句。 我想升级RAM高于数据库大小,但我想避免它,我不知道它是否会更好地解决问题然后分区。
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到1000万行。
数据库大小为10GB我考虑将RAM升级到16GB
答案 0 :(得分:2)
如果您只是想尝试添加分区,我建议您按键使用分区。这基本上只是使用应用于使用分区指定的列的内部哈希函数对表进行分区。
在您的情况下,查询似乎最多使用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个分区。由于我没有指定任何与分区子句一起使用的列,因此MySQL默认使用主键,这在你的情况下会很好。
假设id
列中使用的整数值的合理平衡扩展,每个分区大约为1.25 GB。触发特定id的查询现在应该只从一个分区中选择数据,这样可以更快地访问。
您可以在此处参考MySQL文档:http://dev.mysql.com/doc/refman/5.5/en/partitioning-key.html
毋庸置疑,id是主键,所以这应该已经非常高效了。我不确定可能适用于MyISAM的索引+分区的更多警告。我主要使用InnoDb工作,这就是我所做的,至少使用InnoDb来提高我的查询性能。