大家。这是我的mysql服务器中的一个问题 我有一张大约40,000,000行和10列的表 它的大小约为4GB。发动机是innodb 它是一个master数据库,只执行这样的一个sql。
insert into mytable ... on duplicate key update ...
大约99%的sqls执行update
部分。
现在服务器变得越来越慢。 我听说分裂表可以提高它的性能。然后我尝试在我的个人计算机上,分成10个表,失败了,也尝试了100个,也失败了。速度变慢了。所以我想知道为什么拆分表没有提高性能?
提前致谢。
更多详情:
CREATE TABLE my_table (
id BIGINT AUTO_INCREMENT,
user_id BIGINT,
identifier VARCHAR(64),
account_id VARCHAR(64),
top_speed INT UNSIGNED NOT NULL,
total_chars INT UNSIGNED NOT NULL,
total_time INT UNSIGNED NOT NULL,
keystrokes INT UNSIGNED NOT NULL,
avg_speed INT UNSIGNED NOT NULL,
country_code VARCHAR(16),
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(id), UNIQUE KEY(user_id)
);
PS:
我也尝试过使用固态硬盘和硬盘驱动器的不同电脑,但也没有帮助。
答案 0 :(得分:0)
尝试使用mysql代理将数据库拆分为一些mysql实例,就像mysql-proxy或haproxy而不是一个mysql实例一样。也许你可以有很好的表现。
答案 1 :(得分:0)
拆分桌子根本不可能有所帮助。同上PARTITIONing
。
让我们计算磁盘命中数。我将跳过计算BTrees中的非叶子节点;他们往往被缓存;我将计算数据和索引中的叶节点;他们往往不会被缓存。
IODKU:
UNIQUE
键的索引块。在您的情况下,这可能是user_id
。请提供示例SQL语句。 1阅读。user_id
条目,请从PK(id
)索引的数据中读取记录并执行UPDATE
,并将第二个块保留在buffer_pool最终重写到磁盘。 1现在阅读,1稍后写。INSERT
。已经读取了需要新行的索引块,因此可以插入新条目。同时,表中的“最后一个”块(由于id
为AUTO_INCREMENT
)可能已经被缓存。添加新行。 0现在读,1写稍后(UNIQUE
)。 (重写“最后”块会分摊100行,所以我忽略它。)总计,假设基本上全部采用UPDATE
路径:2次读取和1次写入。假设user_id
没有遵循简单的模式,我将假设所有3个I / O都是“随机的”。
让我们考虑一个变体...... 如果你摆脱id
怎么办?你在其他地方需要id
吗?由于您有一个UNIQUE
密钥,它可能是PK。那就是用PRIMARY KEY(user_id)
替换你的两个索引。现在的计数是:
UPDATE
,0读,1写INSERT
,0读,0写总计:1读,1写。 2/3和之前一样多。更好,但仍然不是很好。
<强>缓存强>
你有多少内存?
innodb_buffer_pool_size
的价值是多少?
SHOW TABLE STATUS
- 什么是Data_length
和Index_length
?
我怀疑buffer_pool不够大,可能会引发。如果你有超过4GB的RAM,那么大约占RAM的70%。
<强>其他强>
SSD应该有很大的帮助,因为你看起来是I / O绑定的。你能说出你是受I / O限制还是受CPU限制?
您一次更新了多少行?多久时间?是批量生产,还是一次批量生产?这里可能会有重大改进。
你真的需要BIGINT
(8个字节)吗? INT UNSIGNED
只有4个字节。
涉及交易吗?
船长有问题吗?奴隶?都?我不想以这样的方式修复大师,以至于它弄乱了奴隶。