2008-11-14 63 views
1

鉴于以下域类:如何在使用Grails hasMany关系时解决潜在的性能问题?

class Post { 
    SortedSet tags 
    static hasMany = [tags:Tag] 
} 

class Tag { 
    static belongsTo = Post 
    static hasMany = [posts:Post] 
} 

从我的理解,到目前为止,使用的hasMany将导致休眠集映射。 但是,为了保持唯一性/顺序,Hibernate需要从数据库加载整个集合并比较它们的哈希值。

如果添加和删除帖子/标签 (如果它们的集合变大),这可能会导致显着的性能问题。解决此问题的最佳方法是什么?

谢谢!

回答

1

默认映射中Hibernate/GORM没有确保顺序。因此,它不需要从数据库加载元素来进行排序。你将手上一堆ID,但这就是它的范围。

参见19.5.2: http://www.hibernate.org/hib_docs/reference/en/html/performance-collections.html

一般来说,休眠/ GORM将不得不比预期更好的性能。除非并且直到您真的可以证明真实世界的性能问题,否则请相信框架并且不要担心。

0

集合的排序由Set实现保证,即SortedSet。除非使用List,它跟踪数据库上的索引,否则排序仅在服务器端。

如果您的域名类别为SortedSet,则必须执行Comparable才能正确排序该设置。

表现问题本身并不是一个真正的问题。如果你想访问一个Tag,你应该得到它的Id。如果你想要排序的标签,那么只要你正在查看所有Tags而不是特定的标签,那么你最终将一次检索所有Tags。由于排序是在服务器端执行的,而不是在数据库端进行的,因此就Db而言,SortedSet和常规的HashSet之间确实没有太大差别。

+0

你有任何文件/证据表明排序为一个在服务器端执行SortedSet的? – 2008-11-19 23:02:01

+0

@Miguel,感谢您的信息,我会深入探讨这个问题。 – Walter 2008-11-20 02:14:57

0

Grails的文档似乎被更新:

http://grails.org/doc/1.0.x/

在第5.2.4,他们讨论的集合类型潜在的性能问题。

这里的相关章节:

的注上集合类型和性能

Java的设置类型是一个集合,不允许重复。为了确保将条目添加到Set关联时的唯一性,Hibernate必须从数据库加载整个关联。如果您在联盟中拥有大量条目,则性能可能会很高。

列表类型需要相同的行为,因为Hibernate需要加载整个关联以维护顺序。因此,如果您预期关联中有大量记录,则建议您将关联设为双向,以便可以在反面创建链接。例如,考虑下面的代码:

def book = new Book(title:"New Grails Book") 
def author = Author.get(1) 
book.author = author 
book.save() 

在这个例子中是由子(书)创建的关联链接,因此它是没有必要的操作集合直接导致较少的查询和更高效的代码。鉴于有大量相关的图书实例的作者,如果你写的代码像下面你会看到对性能的影响:

def book = new Book(title:"New Grails Book") 
def author = Author.get(1) 
author.addToBooks(book) 
author.save()