2011-08-30 26 views
13

Hazırda bekletme, N + 1 sorgu sorunundan kurtulmak için iki seçenek sunar (en az). Biri FetchMode'u Subselect'e ayarlayarak, bu IN cümleciğine bir IN-cümlesi ve bir alt seçimle bir seçim oluşturur. Diğeri, ebeveynlerin kimliklerini içeren bir IN cümleciğine sahip bir seçim üreten bir BatchSize belirtmektir.Hibernate Subselect vs Batch Getirisi

Her ikisi de işe yarıyor; ancak Subselect seçeneğinin, genellikle ebeveynlerin karmaşık olması nedeniyle yapılan sorgulama nedeniyle performans sorunları yaşadığını görüyorum. Öte yandan, büyük bir BatchSize (1000 demek) ile, bu sorguların sorguları ve karmaşıklığı çok azdır.

Benim sorum şu ki: Hibernate'in Subselect FetchMode'u BatchSize üzerinden ne zaman kullanırsınız? Subselect, çok fazla sayıda ana girişiniz varsa (binlerce), ancak BatchSize için bir Subselect'i tercih edeceğiniz başka senaryolar varsa, mantıklı olabilir.

DÜZENLEME: İstekli yükleme ile ilgilenirken ikisi arasında bir fark fark ettim. Hevesli bir şekilde ve bir alt seçim yoluyla yüklenecek bir xToMany ilişki kümeniz varsa, tembel olsaydı böyle bir alt seçim oluşturur. Ancak bir BatchSize belirtirseniz, oluşturulan sorgu ayrı bir sorgu yerine bir dış birleştirmeyi kullanır. Hazırda yüklerken Hazırda bekletme sorgusunu kullanmak için Hazırda bekletmenin herhangi bir yolu var mı?

cevap

13

Alt denetim kullanmıyorum çünkü denetimi zor. Karmaşık iş mantığına ve üzerinde çalışan büyük bir takıma sahip olan çok büyük bir sistemde, hangi sorguların kullanıldığını söylemek çok zor. Subselect, hangi sorgunun gerçekleştirildiğini tam olarak bildiğiniz belirli durumlarda çalışabilir.

Toplu getirmenin bazı büyük avantajları vardır. Her zaman en hızlı değil, ama genellikle yeterince hızlıdır. Diğer yandan çok kararlı, herhangi bir yan etkisi yok ve iş mantığına tamamen şeffaf. 100'den daha yüksek olan parti değerlerini asla kullanmam. N + 1'i makul miktarda sorguya indirgemek yeterlidir.

+2

Neden alt denetimin kontrol edilmesi zor olduğunu anlamıyorum. Biraz ışık atabilir misin? –

+0

Subselect, daha önce yürütülen sorguya göre değişir. Bu sorgu çok karmaşık olabilir, ör. diğer tabloların bir çok kullanılması ve dizine eklenmemiş sütunlar tarafından filtrelenmesi. Bu nedenle, alt sorgu yaklaşımının performansı artırması olasıdır. –

+1

Subselect ile ilgili başka bir sorun da MySQL ile kırpılabilir; MySQL (5.5 ve aşağısı) iç içe geçmiş sorgularla korkunç performansa sahiptir, çünkü bunları zorla ilişkilendirir ve üst sorgudaki her satır için tekrar değerlendirir. Hibernate'in açıklamalı bir ilişki için iç içe geçmiş bir sorgu oluşturması için başka bir yol bulamıyorum, bu yüzden alt seçimden kaçınmak MySQL ile kötü bir sürpriz olmasını önleyecektir. –

2

Yardımcı olmak için this article numaralı telefonu buldum. Subselect yalnızca bir koleksiyona uygulanabilirken, toplu alımın hem koleksiyona hem de ana bilgisayara uygulanabileceğine inanıyorum.

Koleksiyonlar için bir getirme stratejisi olması durumunda, bir alt seçim bir kez gerçekleştirilir (toplu boyutun etkin bir şekilde sonsuz olduğu için), toplu alımda SQL deyimi birden çok kez gerçekleştirilebilir.