2009-05-13 9 views
0

In meinem System mache ich eine zentralisierte Berechnung auf einem Aggregat mit vielen Sammlungen. Ich brauche ALLE Sammlungen, die vor der Berechnung geladen werden, und deshalb verwende ich eine Multikriterien, die die Sammlungen auf der Wurzel verbindet.Optimize NHibernate Query

Die Kriterien, die ich hier unten aufgeführt. Es dauert ca. 500ms, um auf meinem lokalen Setup zu laufen, und das ist eine Menge Wartezeit für den Benutzer. Hat jemand eine Idee, wie ich das optimieren könnte? Jede Hilfe, die diese Abfrage schneller machen kann, wird geschätzt!

IMultiCriteria criteria = session.CreateMultiCriteria() 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ACollection", JoinType.LeftOuterJoin) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("BCollection", JoinType.LeftOuterJoin) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("CCollection", JoinType.LeftOuterJoin) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ECollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("FCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("GCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("HCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("JCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("KCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("LCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("MCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("NCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("OCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("PCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("QCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("RCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("SCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("TCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("UCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("VCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("WCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("XCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("YCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ZCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("AACollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ABCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ACCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("ADCollection", JoinType.LeftOuterJoin)) 
.Add(DetachedCriteria.For<Building>() 
    .Add(Restrictions.Eq("Id", BuildingId)) 
    .CreateCriteria("AECollection", JoinType.LeftOuterJoin)); 
(Ich habe die Namen der Kollektionen für eine wenig Privatsphäre :) geändert)
+0

wow ... beeindruckend –

+0

hehe ... ja, ich sicher, wünsche ich eine andere Wahl hatte! :) – asgerhallas

Antwort

1

Das allererste, was ich empfehlen könnte, wäre die SQL Profiler, um Feuer und eine exakte Kopie des SQL erhalten kommend. Dann würde ich das nehmen und es in den Sql-Tuner legen, dies wird höchstwahrscheinlich empfehlen, neue Indizes zu erstellen und Statistiken zu einigen oder allen Tabellen hinzuzufügen/zu aktualisieren.

An diesem Punkt würde ich dann die Leistung testen, bevor Sie in den Versuch, die HQL Performance-Tuning tun.

2

Nach einiger Zeit wurde mir klar, dass es für dieses genaue Szenario sinnvoller ist, eine dokumentenorientierte Datenbank wie MongoDB oder eine Objektdatenbank zu verwenden.

So kann ich das gesamte Aggregat auf einmal laden und Joins vergessen.

Also für jeden, der in Szenarien wie dem oben genannten auftritt, überlegt, einen dokumentenorientierten Ansatz zu verwenden.

Meine ersten Tests zeigt Versprechen :)

Eine Einführung in MongoDB finden Sie hier: http://mookid.dk/oncode/archives/1057