2009-11-23 21 views
9

Son zamanlarda oldukça garip bir fenomen geçirdim. Farklı WHERE koşulları ile birden fazla tablo üzerinde birleştirmeler içeren bir sayı elde etmek zorunda kaldı. Sorguyu ilk olarak hazırda bekletme ölçütü API'sı ile uyguladım. İstenen hazırlanan SQL deyimini doğru şekilde oluşturdu ancak oldukça yavaştı. Daha sonra HQL kullanarak tüm sorguyu yeniden uyguladı. Bunu yapmak oldukça kötüydü, ancak sonuç Kriter İdaresi API'sinden çok daha hızlı gerçekleşti. Bu davranışın nedenini bilen var mı? Kriterler ve HQL çerçevesinin, SQL'e dönüştürmek için aynı kod tabanını kullandığını farz ettim.Hazırda Bekleme Sorgularına Göre Kriter Performans

select count(*) from R r where r.ISREPLACEDBY = 0 
and r.STATUS='OK' and r.A = ? 
and r.C in 
    (select distinct RC from CX cx where cx.FROMDATE >= ? and cx.FROMDATE <=?) 
+0

bazı ek bilgi okuyabilir? –

+0

Sorgu, parametrelere bağlıdır. Daha basit kayıtlardan biri aşağıdaki gibidir: R r'den seçim sayısı (*), burada r.ISREPLACEDBY = 0 ve r.STATUS = 'OK' ve r.A =? ve r.C in (CX cx'den cx.FROMDATE> =? ve cx.FROMDATE <=? 'dan farklı RC'yi seçin.) – bertolami

cevap

17

Nihayet sebebini buldum. Öyle görünüyor ki, kriterler api, hazırlanmış bir deyim her yürütüldüğünde yeni değişken adlar oluşturur. Veritabanı (bizim durumumuzda, DB2), her deyim yürütüldüğünde, yeni bir sorgu yürütme planı hesaplar. Öte yandan, HQL aynı değişken isimlerini kullanır ve veritabanının sorgu yürütme planlarını yeniden kullanmasına izin verir.

0

Genellikle birkaç oyuncu değişikliği ile neredeyse düz bir SQL olduğu gibi HQL çok optimum yakın olduğuna inanıyoruz: Burada

sorgusu olur. HQL'den SQL'e yapılan çevirinin sadece ikame olduğunu varsayalım; Kriterler API'sı muhtemelen dönüştürülecek HQL üretir. Genel olarak HQL en iyi bahistir.

+2

Aslında, Kriterler doğrudan SQL'e çevrilir. Örneğin. Criterion.toSqlString – qualidafial

+0

Bu aslında doğru değil. İlk önce HQL üretir ve daha sonra ayrıştırılır. – mnp

0

hazırda Kriterleri (ı alırsınız adlandırılmış sorguları hariç) bir HQL sorgusu daha az ek yük olmalıdır teoride,

+0

Kriterlerin API'siyle ilgili bir diğer sorun, HQL'yi her seferinde oluşturmasıdır (her seferinde farklı olabileceği için). Bu HQL ayrıca her seferinde SQL'e çevrilir. Bu çeviri, ClassNotFoundException kullanan sınıf yükleyiciden (örn. OluşturulanBla0) bazı tokenleri yüklemeye çalışır. Bu, sonuncusu bir istisna atabilmesinden önce tüm sınıf yükleyicilerinden geçerken oldukça pahalı bir işlemdir ve aynı zamanda performansı az bir şekilde etkileyen sınıf yükleyicide bazı kilitler içerir. Bir hata tamsayıları nedeniyle, params yerine SQL'e eklenebilir. – mnp

3

Kriterleri SQL statments oluşturmak için yansıma kullanın. Bunun nedeni, Kriterleri hiçbir şeyi ayrıştırmak zorunda değil. HQL sorguları bir ANTLR tabanlı çözümleyici ile ayrıştırılır ve sonuçta oluşan AST, SQL'e dönüştürülür. Ancak, HQL/JPAQL ile, SessionFactory başlatıldığında SQL'in oluşturulduğu adlandırılmış sorguları tanımlayabilirsiniz. Teoride, adlandırılmış sorguların Kriterlere göre daha az başı vardır. Yani, SQL nesil yükü bakımından elimizdeki:/JPAQL Sorgu HQL Named

  1. - SQL üretimi sadece bir kez olur.
  2. Kriterler - Oluşturmadan önce ayrıştırmaya gerek yoktur.
  3. (adlandırılmamış) HQL/JPAQL Sorgu - Ayrıştırma, sonra üret. Bu, ayrıştırma ve SQL nesil yükünü temel alan bir sorgu tekniği seçmek muhtemelen benim düşüncemde bir hata olduğunu söyledi. Gerçek veri ile gerçek bir veritabanı sunucusunda gerçek bir sorguyu gerçekleştirmeye kıyasla, bu ek yük genellikle çok küçüktür. Uygulamanın profilini oluştururken bu ek yük gerçekten görünürse, belki de adlandırılmış bir sorguya geçmelisiniz. İşte

Kriterleri ve HQL/JPAQL arasında karar verirken bunu göz önünde noktalar şunlardır:, içeri hazırda-özel API bir bağımlılık sahip iyisin eğer karar vermek zorunda

  • İlk senin kodu. JPA’da Kriterler yok. çok parametreli bir parametre ile, çok parametre 'arama formu' gibi tipik bir web sayfasında bulabilirsiniz. HQL ile, geliştiriciler StringBuilder ile ifadelerinin nerede olduğunu anlamaya meyillidir (bundan kaçın!). Kriterlerle, 'un bunu yapmanıza gerek yoktur.
  • HQL/JPAQL diğer birçok şey için kullanılabilir, çünkü kod, geliştiricilerin anlaması için 'un daha küçük ve daha kolay olma eğilimindedir.
  • HQL kullanıyorsanız, çok sık kullanılan sorgular adlandırılmış sorgulara dönüştürülebilir. Bunu bir profil yaptıktan sonra yapmayı tercih ederim.

Sen HQL ve Kriterler sorguları gösterebilir miyim burada http://tech.puredanger.com/2009/07/10/hibernate-query-cache/

İlgili konular