我有一个很大的桌子,我对它进行了非常简单的查询,例如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/

10-11 02:48
查看更多