我想在一个足球幻想游戏中尝试MySQL Partitioning,用户在联盟中分发,每个联盟都有一个用户可以出售或购买玩家的市场。当许多用户同时玩游戏时,我在这张桌子中遇到了一些僵局(在写作时大约有50K联赛,市场上大约有20名玩家每两天刷新一次),所以我我正在考虑使用MySQL分区,我之前没有使用过它。
这是我要分区的表格:
CREATE TABLE `market` (
`leagueID` int(10) unsigned NOT NULL,
`playerID` smallint(5) unsigned NOT NULL,
`userID` int(10) unsigned DEFAULT,
`price` int(10) unsigned NOT NULL ,
`date` int(10) unsigned NOT NULL,
UNIQUE KEY `league_player` (`leagueID`,`playerID`),
KEY `user_date` (`userID`,`date`)
);
您建议使用哪种方法(列,范围,分区数等)?
这是我最初的做法:
ALTER TABLE market
PARTITION BY HASH(leagueID)
PARTITIONS 10;
答案 0 :(得分:1)
为什么要分区?
我问,因为大多数分区尝试都没有收获。没有性能提升;有时性能下降。特别是BY HASH
很少有帮助。
您使用的是MyISAM吗?如果这样切换到InnoDB。既然你提到过“死锁”,你可能已经在使用InnoDB吗?分区不会对事务死锁有所帮助;我们需要查看两个事务中的查询。解决方案可能与排序IN
列表一样简单。
但是......无论我们是否解决了这些问题。您今天遇到的僵局,您需要检查错误并重播已中止的整个事务。这是解决问题的唯一可靠方法。死锁。
Datacharmer的幻灯片为您提供了血腥的细节; my blog列出了PARTITIONing
非常有用的极少数情况,从而使他的大多数幻灯片无效。
其他问题......
PRIMARY KEY
。建议您将UNIQUE
密钥更改为PRIMARY KEY
。 InnoDB确实需要PK。DATE
数据类型;使用它可能不像某些INT
那样笨拙。答案 1 :(得分:0)
我现在已经看过几次类似的东西了,我不相信分区会解决你的问题。
您在唯一索引上看到的死锁可能是由于两个使用锁定所在的相同数据库页的非冲突违规插入。由于索引的B树结构,如果一个联盟在特定时间窗口中写得很重(似乎是合理的),那么该页面上的互斥锁将会遇到竞争条件的可能性更高。
我会考虑通过更改唯一约束中两个字段的顺序来物理分发索引“热点”,并将现有索引添加为常规索引(出于查找原因)。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="form1">
<form name='test'>
<label><input type="checkbox" image="https://placebear.com/300/200" name="field" value="one">BASE</label>
<label><input type="checkbox" image="https://placebear.com/300/300" name="field" value="two">Deep Well </label>
<label><input type="checkbox" image="https://placebear.com/200/200" name="field" value="three">Extension </label>
<label><input type="checkbox" image="https://placebear.com/200/300" name="field" value="four">Treadmill</label>
<label><input type="checkbox" image="https://placebear.com/300/250" name="field" value="five">Stairs </label>
</form>
</div>
<div id="imagetest">
</div>
就此而言,由于您还没有主键(but InnoDB is gonna create one behind the scenes anyway),因此从逻辑上讲,新键可以承担该角色。
ALTER TABLE `market`
ADD UNIQUE KEY player_league (`playerID`,`leagueID`),
DROP UNIQUE KEY `league_player`,
ADD KEY league_player (`leagueID`,`playerID`);