【Hibernate】 Performance Tuning
来源:互联网 发布:js 设置input编辑状态 编辑:程序博客网 时间:2024/06/03 23:41
Fetching Strategy
Eager Fetching
Eagerly fetched associations or collections will be fetched when loading their parent object. Retrieving unnecessary data imposes extra load on both the database server and the application server and may also reduce the concurrency of the system, creating too many unnecessary read locks at the database level. In JPA, all toOne(@OneToOne, @ManyToOne) mappings default to eager fetching, others default to lazy fetching, while as far as Hibernate concerned, all mappings default(recommended) to lazy fetching.
Annotation: @OneToMany(fetch = FetchType.EAGER)
Actually, Hibernate offers two options in terms of eager fetching: FetchMode.JOIN and FetchMode.SELECT.
FetchMode.JOIN
In this mode, Hibernate will generate a big select with a number of outer joins to eagerly fetch associations or collections.
Annotation: @Fetch(FetchMode.JOIN)
FetchMode.SELECT
In this mode, Hibernate will generate a number of relatively small select to eagerly fetch associations or collections one by one.
Lazy Fetching
Annotation: @Fetch(FetchMode.SELECT)
For associations, lazy fetch can be divided into:
Proxy Fetching
For associations, a single-valued association is fetched when a method other than the identifier getter is invoked upon the associated object.
For parent object itself, session.load(identifier) wouldn't hit database instead just return a proxy carrying its identifier, but if you invokesession.get(1), it would hit database. Therefore, you can invoke session.get() instead of session.load() to avoid proxy generation at run-time.
No-proxy" Fetching
The association is fetched even when only the identifier is accessed. This approach requires buildtime bytecode instrumentation and is rarely necessary.
Annotation: @org.hibernate.annotations.Proxy(lazy = false)
For collections, lazy fetch can be divided into:
Lazy Collection Fetching
A collection is fetched when the application invokes an operation upon that collection.
Annotation: @ManyToOne(fetch = FetchType.LAZY)
"Extra-lazy" Collection Fetching
size(), isEmpty(), contains() methods don't trigger fetching collections in contrast to non-extra lazy collection fetching.
Annotation: @org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)
N+1 Select Problem
When applying lazy fetching, it has potential to cause so-called N+1 select problem, which in short means the entire transaction requires 1 initial select that retrieves the parent objects plus N additional selects to load the children collections of each parent. It can be handled by following approaches:
Batch Fetching
If one association or collection of a parent object is accessed, go ahead and initialize the same associations or collections of several other parent objects in the same SELECT query. This turn N+1 queries into N/s + 1 queries, where s is the batch size that you can set.
Annotation: @org.hibernate.annotations.BatchSize(size = 10)
Sub-select Fetching
For batch fetching, you’d need to figure out an optimum batch size by trial. A much better optimization is sub-select fetching, which initialize the same associations or collections of ALL other parent objects in the same SELECT query. It combines the initial query and later query by using initial query as a sub-select in the where clause of later query.
Annotation: @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
Guidelines
Normally, you would be always using lazy fetching for all associations or collections(declare this as global strategy in mapping file or annotations).
Run-Time(Code-Level) Declarations
However, sometimes in some use cases you definitely know that certain association or collection objects will be needed right after loading its parent. In such cases, you can apply run-time declarations which enables eager fetching for one query alone by calling setFetchMode() orFetchMode.JOIN when query by HQL or criteria.
Explicitly Initializing
A LazyInitializationException will be thrown by Hibernate if an uninitialized collection or proxy is accessed outside of the scope of the Session. Therefore, we need to ensure that a proxy or collection is initialized before closing the Session. If we know session is about to be closed, before that we can use Hibernate.initialize() to explicitly fetch associations or collections(Hibernate.isinitialize() can be used to test). For example, Hibernate.initialize(solution.getDataplans()) will trigger fetching all data plans of solution even if it is originally lazy fetched.
Cache
To be continued...
- 【Hibernate】 Performance Tuning
- performance tuning
- ORACLE PERFORMANCE SQL TUNING
- Performance Tuning Strategies.
- Performance Tuning Techinques.
- Java Performance Tuning
- WSAD Performance Tuning(转贴)
- weblogic performance tuning
- [连载]Tuning .NET Performance
- Oracle Performance Tuning
- Performance Tuning Methodology
- Java performance tuning
- SQL Performance Tuning
- Performance tuning link
- 5.Performance Tuning
- (JRuby) Performance Tuning
- Performance Tuning Guide
- Struts Performance tuning
- <<Think in Java 4 >>中关于使用XOM操作xml文件
- 【Spring】@Autowired and @Resource
- ruby on rails 问题解决
- 母函数学习
- hdu1272 小希的迷宫 hdu1856 More is better
- 【Hibernate】 Performance Tuning
- 黑马程序员_面试题--交通灯总结
- Android读取SD卡下面所有的TXT文件名 listView显示出来
- 我的学习生涯(Delphi篇) - 06
- Linux Netcat 命令——网络工具中的瑞士军刀
- qt多线程、事件调度 http://www.xue5.com/Developer/Software/608233.html
- 把AIR隐藏在系统托盘中,并添加系统托盘菜单
- maven tomcat eclipse 配置 debug
- c++中冒号(:)和双冒号(::)的用法和c/c++ 位域结构体