繁体   English   中英

MySQL JPQL查询性能问题

[英]MySQL JPQL query performance issue

我正在构建一个我打算成为一个持久在线世界的游戏(例如MMO,但可能不是大量的玩家。)我正在通过仅创建一个2D的“平铺”网格来制作游戏地图。 我已经将磁贴持久保存到数据库中了,并且已经设置了网页UI(通过Vaadin),以便可以正常查看它们。 到目前为止,我最常在20x20的网格中查看它们。

到现在为止,它似乎进展顺利。 我可以保留几套10,000张磁贴,然后滚动查看它们并重新显示磁贴几乎是瞬时的。 但是,今天,我决定保留一堆切片(准确地说是633,460),以查看数据库中更实际的切片数量是什么样子。 现在,我在地图上滚动时遇到了一些重大的性能问题,因为我的MySQL数据库似乎很难处理那么多图块。

我正在使用Hibernate支持的JPA 2.0。 即使直接进入数据库并运行SQL查询,响应时间也非常慢。

SELECT * FROM game.landtile WHERE xcoor < 999999061 AND xcoor >  999999040
AND ycoor > 1000000140 AND ycoor < 1000000161;

我只是运行了该查询以获取400个地块,因此它的持续时间为3.5秒,而直接在MySQL中的获取时间为7.25秒! 如果我第二次运行相同的查询,则其持续时间为0.5秒,提取时间为0.1秒。 我可以忍受500毫秒,而我不能忍受7,000。

我的实体名称如下:

@Entity
@Table(name = "LandTile", uniqueConstraints = {@UniqueConstraint(columnNames={"XCoor", "YCoor"})})
public class LandTile extends AbstractMapValues implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "LandTileId")
    private String landTileId;

    @Column(name = "XCoor")
    @Index(name = "XCoordinateIndex")
    @Range(min = 0, max = MAX_MAP_INT)
    private int xCoor;


    @Column(name = "YCoor")
    @Index(name = "YCoordinateIndex")
    @Range(min = 0, max = MAX_MAP_INT)
    private int yCoor;

    @OneToOne(cascade = CascadeType.ALL)
    private Building building;

    @OneToOne(cascade = CascadeType.ALL)
    private Road road;

    private boolean river;

    @OneToMany(mappedBy="expeditionLocationLandTile")
    private Set<Expedition> expeditionsAtThisLocation;

    @ManyToMany(
            mappedBy = "discoveredLandTiles",
            targetEntity = Player.class
        )

    private Set<Player> playersThatHaveDiscovered;

    @ManyToMany(
            mappedBy = "routeListOfLandTiles",
            targetEntity = Expedition.class
        )
    private List<Expedition> expeditionRouteThisIsPartOf;

    @ManyToOne
    @JoinColumn(name="FiefdomOfCapitalCity", unique=true)
    private Fiefdom fiefdomOfCapitalCity;

    @ManyToOne
    @JoinColumn(name="ActualOwningFiefdomId", unique=true)
    private Fiefdom actualOwningFiefdom;

    @ManyToOne
    @JoinColumn(name="DefaultOwningFiefdomId", unique=true)
    private Fiefdom defaultOwningFiefdom;

还有另外18个简单的int列,我没有在这里列出。

所以基本上我希望你们能帮助我弄清楚我的选择。 如您所见,Landtile与其他模型之间存在许多关系,对于这样的游戏,整个数据集本身是高度相关的,这就是为什么我首先使用SQL数据库的原因。 但是现在我担心性能太差了,以至于我应该停止开发新功能,并重做我的整个DAO层(希望只是...)以使用NoSQL数据库并处理与我在Java中的所有关系。

看起来MongoDB内置了对2d网格的支持:

http://blog.codecentric.de/zh/2012/02/spring-data-mongodb-geospatial-queries/

我当时计划可能将游戏托管在Amazon上,并使用Amazon Elasti-cache。 我的游戏地图数据是否有可能大部分停留在第二级缓存中(通过休眠),因此我不会有这种可怕的表现? 我真的认为,我会遇到的关于MySQL的唯一真正的性能问题就是在愚蠢的地图上滚动!

我的数据是空间数据,而MySQL的InnoDB引擎不支持空间索引。 MyISAM引擎可以,但是不支持事务或外键。 参见MySQL文档

我决定不使用牺牲事务和外键的方式,而是决定使用支持复杂关系,事务和外键的数据库,因此我将整个项目切换为使用Neo4j图形数据库

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM