Leg*_*end 31 mysql database database-design partitioning
简要回顾一下发生的事情.我正在处理7100万条记录(与其他人处理的数十亿条记录相比并不多).在另一个线程上,有人建议我的群集的当前设置不适合我的需要.我的表结构是:
CREATE TABLE `IPAddresses` (
`id` int(11) unsigned NOT NULL auto_increment,
`ipaddress` bigint(20) unsigned default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
Run Code Online (Sandbox Code Playgroud)
我添加了7100万条记录,然后做了一个:
ALTER TABLE IPAddresses ADD INDEX(ipaddress);
Run Code Online (Sandbox Code Playgroud)
这是14个小时,操作仍未完成.通过谷歌搜索,我发现有一个众所周知的方法来解决这个问题 - 分区.我知道我现在需要根据ipaddress对我的表进行分区,但是我可以在不重新创建整个表的情况下执行此操作吗?我的意思是,通过ALTER声明?如果是,则有一个要求说要分区的列应该是主键.我将使用这个ipaddress的id来构建一个不同的表,所以ipaddress不是我的主键.在这种情况下,如何对表格进行分区?
Leg*_*end 39
好的事实证明,这个问题不仅仅是一个简单的创建表,索引它并忘记问题:)这是我做的,以防万一其他人面临同样的问题(我已经使用了一个IP地址的例子,但它适用于其他数据类型):
问题:您的表有数百万个条目,您需要快速添加索引
用例:考虑在查找表中存储数百万个IP地址.添加IP地址应该不是一个大问题,但在它们上创建索引需要超过14个小时.
解决方案:使用MySQL的Partitionin g策略对表进行分区
案例#1:当你想要的表尚未创建时
CREATE TABLE IPADDRESSES(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ipaddress BIGINT UNSIGNED,
PRIMARY KEY(id, ipaddress)
) ENGINE=MYISAM
PARTITION BY HASH(ipaddress)
PARTITIONS 20;
Run Code Online (Sandbox Code Playgroud)
案例#2:当您想要的表已经创建时. 似乎有一种方法可以使用ALTER TABLE来做到这一点,但我还没有想出一个适当的解决方案.相反,有一个效率稍低的解决方案:
CREATE TABLE IPADDRESSES_TEMP(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ipaddress BIGINT UNSIGNED,
PRIMARY KEY(id)
) ENGINE=MYISAM;
Run Code Online (Sandbox Code Playgroud)
将您的IP地址插入此表.然后使用分区创建实际表:
CREATE TABLE IPADDRESSES(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
ipaddress BIGINT UNSIGNED,
PRIMARY KEY(id, ipaddress)
) ENGINE=MYISAM
PARTITION BY HASH(ipaddress)
PARTITIONS 20;
Run Code Online (Sandbox Code Playgroud)
最后
INSERT INTO IPADDRESSES(ipaddress) SELECT ipaddress FROM IPADDRESSES_TEMP;
DROP TABLE IPADDRESSES_TEMP;
ALTER TABLE IPADDRESSES ADD INDEX(ipaddress)
Run Code Online (Sandbox Code Playgroud)
你去了...在新桌面上索引花了我大约2个小时在3.2GB机器上1GB RAM :)希望这有帮助.
使用MySQL创建索引很慢,但速度并不慢.拥有7100万条记录,需要几分钟而不是14小时.可能的问题是:
看这里:http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_myisam_sort_buffer_size
如果您尝试使用8MB排序缓冲区生成1GB索引,则需要大量传递.但是如果缓冲区大于CPU缓存,它将变慢.所以你必须测试并看看什么效果最好.
像往常一样检查iostat,vmstat,logs等.在你的桌子上发出一个LOCK TABLE来检查是否有人锁定它.
我的64位桌面上的FYI在10M随机BIGINT上创建索引需要17秒......
我有问题,我希望通过添加索引加快我的查询.该表只有大约300,000条记录,但也花了太长时间.当我检查mysql服务器进程时,结果发现我试图优化的查询仍然在后台运行.4次!在我杀死这些查询之后,索引是在快速完成的.也许同样的问题适用于您的情况.
| 归档时间: |
|
| 查看次数: |
48666 次 |
| 最近记录: |