2016-06-09 11 views
1

Ich habe die folgende Abfrage in SSMS2008:Abfragegeschwindigkeit in SQL Server Management Studio (2008) vs NHibernate session.Query

select * 
from Measurements 
where dt > '2016-01-01 04:00:00' 
    and dt < '2016-01-01 04:05:00' 
    and classification = 'heartbeat' 

Meine Tabelle hat mehr als 400 Millionen Datensätze in ihm, Herzschlag und andere Daten (I wissen), aber obige Abfrage in weniger als 1 Sekunde (ruft etwa 1500 Datensätze). Es gibt Indizes für die Spalten dt und classification.

Wenn ich diese Abfrage in NHibernate verwenden:

var heartbeats = session.Query<Measurements>() 
         .Where(m.dt > dtFr && 
           m.dt < dtTo && 
           m.classification = 'heartbeat') 
         .ToList(); 

.. jedoch versagt diese Abfrage. Das einzige, was anders ist (soweit ich sehen kann), ist, dass ich DateTime-Objekte (und dtTo) verwenden und sie an die linq Ausdruck übergeben. Wenn diese Abfrage jedoch fehlschlägt (Timeout), kann ich die fehlgeschlagene Abfrage kopieren und in SSMS2008 einfügen, und sie wird dort ohne Probleme ausgeführt.

Edit: gestern habe ich viel zu viel Tests und ich habe Dinge durcheinander gebracht. Es scheint, dass die fehlgeschlagene Abfrage nicht ausgeführt wird (keine von SSMS). Ich kann nicht sehen, was ich falsch mache.

+0

Also, was ist die Frage jetzt? Schwer zu helfen, wenn Sie nicht wissen, was Sie tun ... –

Antwort

0

Ich würde wahrscheinlich sagen, dass die erste Auswahl auf dem SQL-Server verarbeitet wird. (Offensichtlich, wie Sie es mit dem Management Studio getestet haben)

Ich denke, was passiert ist, dass die Abfrage im Code alle Daten vom SQL-Server anfordert und danach die Suche in Ihrer lokalen Anwendung durchführt.

Ich könnte falsch liegen, da ich nicht weiß, wie linq eine where-Klausel verarbeitet, aber es klingt für mich, als ob dies der Fall sein könnte.

Prost

Thomas

1

Es fehlt Informationen über Mapping, die in diesem Moment die meisten Verdacht zu sein scheint. Und zwar für den Fall, dass es Referenzen ist im Zusammenhang mit einigem nicht-Standard zu holen (nicht faul, der Standard ist und in der Tat der besten)

zu beheben (oder vielleicht zu vermeiden) solche Ausstellung, die Verwendung Projektion. Auf diese Weise wird NHibernate laden und späteren Prozess nur erforderlichen Felder

var heartbeats = session.Query<Measurements>() 
    .Where(m.dt > dtFr && 
     m.dt < dtTo && 
     m.classification = 'heartbeat') 
    .Select(x => new {m.dt, m.classification }) 
    .ToList(); 

Andere Wörter, die Differenz zwischen rohen SQL und Endverarbeitung mit NHibernate ... ist in der Regel Materialisierung. Seien Sie sicher, dass Sie das hier reduzieren ... und die Ergebnisse sollten schnell wie eine direkte SQL-Ausführung sein.