0

我有一个非常大的表,我在上面执行了一个非常简单的查询,比如 id 查找。由于表行的增加,查询随时间变慢。我在一秒钟内执行了大约 300 个查询,这使我的脚本运行缓慢并且我的内存达到 99%(内存低于数据库的大小)我想对表进行分区和子分区以获得最大性能,这是我的表(out 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

4

1 回答 1

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,以提高我的查询性能。

于 2012-10-15T10:33:37.693 回答