Hibernate-Abfrage ohne großen Listenparameter neu schreiben

9

In meiner Datenbank habe ich eine zip Tabelle mit einer code Spalte. Der Benutzer kann eine Liste von Postleitzahlen hochladen und ich muss herausfinden, welche bereits in der Datenbank sind. Derzeit verwende ich die folgende Hibernate-Abfrage (HQL):

%Vor%

Der Wert des Parameters :zipCodes ist die Liste der vom Benutzer hochgeladenen Codes. In der Version von Hibernate, die ich verwende, gibt es jedoch einen Fehler , der die Größe solcher Listenparameter begrenzt Gelegenheiten überschreiten wir diese Grenze.

Ich muss also einen anderen Weg finden, um herauszufinden, welche der (möglicherweise sehr langen) Postleitzahlen bereits in der Datenbank sind. Hier sind einige Optionen, die ich in Betracht gezogen habe

Option A

Schreiben Sie die Abfrage mit SQL statt mit HQL neu. Während dies den Hibernate-Fehler vermeiden wird, vermute ich, dass die Leistung schrecklich sein wird, wenn 30.000 Postleitzahlen vorhanden sind, die überprüft werden müssen.

Option B

Teilen Sie die Liste der Postleitzahlen in eine Reihe von Unterlisten auf und führen Sie eine separate Abfrage für jede Unterliste aus. Auch dies wird den Hibernate-Fehler vermeiden, aber die Leistung wird wahrscheinlich immer noch schrecklich sein

Option C

Verwenden Sie eine temporäre Tabelle, d. h. fügen Sie die zu prüfenden Postleitzahlen in eine temporäre Tabelle ein, und verbinden Sie diese mit der Tabelle zip . Es scheint, dass der abfragende Teil dieser Lösung einigermaßen gut funktionieren sollte, aber das Erstellen der temporären Tabelle und das Einfügen von bis zu 30.000 Zeilen wird nicht funktionieren. Aber vielleicht gehe ich nicht den richtigen Weg, hier ist, was ich im Pseudo-Java-Code im Sinn hatte

%Vor%

Gibt es einen effizienteren Weg, dies zu implementieren als im obigen Pseudo-Code, oder gibt es eine andere Lösung, an die ich nicht gedacht habe? Ich benutze eine Postgres-Datenbank.

    
Dónal 10.12.2012, 10:14
quelle

5 Antworten

1
___ answer13799003 ___

Option D:
Laden Sie alle vorhandenen Postleitzahlen aus der Datenbank (Paginierung?) Und machen Sie den Vergleich in Ihrer Anwendung.

Was Ihre Option A betrifft:
Ich erinnere mich an eine Beschränkung der SQL-Abfrage Länge, aber das war auf DB2, ich weiß nicht, ob es eine Beschränkung für PostgreSQL gibt.

    
___ qstntxt ___

In meiner Datenbank habe ich eine removeAll(databaseList) Tabelle mit einer %code% Spalte. Der Benutzer kann eine Liste von Postleitzahlen hochladen und ich muss herausfinden, welche bereits in der Datenbank sind. Derzeit verwende ich die folgende Hibernate-Abfrage (HQL):

%Vor%

Der Wert des Parameters %code% ist die Liste der vom Benutzer hochgeladenen Codes. In der Version von Hibernate, die ich verwende, gibt es jedoch einen Fehler , der die Größe solcher Listenparameter begrenzt Gelegenheiten überschreiten wir diese Grenze.

Ich muss also einen anderen Weg finden, um herauszufinden, welche der (möglicherweise sehr langen) Postleitzahlen bereits in der Datenbank sind. Hier sind einige Optionen, die ich in Betracht gezogen habe

Option A

Schreiben Sie die Abfrage mit SQL statt mit HQL neu. Während dies den Hibernate-Fehler vermeiden wird, vermute ich, dass die Leistung schrecklich sein wird, wenn 30.000 Postleitzahlen vorhanden sind, die überprüft werden müssen.

Option B

Teilen Sie die Liste der Postleitzahlen in eine Reihe von Unterlisten auf und führen Sie eine separate Abfrage für jede Unterliste aus. Auch dies wird den Hibernate-Fehler vermeiden, aber die Leistung wird wahrscheinlich immer noch schrecklich sein

Option C

Verwenden Sie eine temporäre Tabelle, d. h. fügen Sie die zu prüfenden Postleitzahlen in eine temporäre Tabelle ein, und verbinden Sie diese mit der Tabelle %code% . Es scheint, dass der abfragende Teil dieser Lösung einigermaßen gut funktionieren sollte, aber das Erstellen der temporären Tabelle und das Einfügen von bis zu 30.000 Zeilen wird nicht funktionieren. Aber vielleicht gehe ich nicht den richtigen Weg, hier ist, was ich im Pseudo-Java-Code im Sinn hatte

%Vor%

Gibt es einen effizienteren Weg, dies zu implementieren als im obigen Pseudo-Code, oder gibt es eine andere Lösung, an die ich nicht gedacht habe? Ich benutze eine Postgres-Datenbank.

    
___ qstnhdr ___ Hibernate-Abfrage ohne großen Listenparameter neu schreiben ___ answer13799060 ___

Haben Sie versucht, Unterabfragen IN zu verwenden?

Ссылка

wäre so etwas

%Vor%

sry, wenn ich den Code irreführe, es dauert eine Weile, da ich Hibernate nicht verwende

    
___ answer13799995 ___

Es gibt ungefähr 45'000 Postleitzahlen in den USA und die scheinen auf dem neuesten Stand zu sein. Wenn dies ein jährlicher Job ist, schreib es nicht in Java. Erstellen Sie ein SQL-Skript, das die Postleitzahlen in eine neue Tabelle lädt und eine Insert-Anweisung mit

schreibt

%code%

Lassen Sie Ihre Mitarbeiter dieses zwei Zeilen umfassende SQL-Skript einmal pro Jahr ausführen und kaufen Sie sich das nicht im Java-Code. Plus, wenn Sie dies aus Java heraushalten, können Sie grundsätzlich jede Annäherung angehen, weil es niemanden interessiert, ob das für 30 Minuten in Offpeak-Zeiten läuft.

teile und imperra

    
___ tag123sql ___ Structured Query Language (SQL) ist eine Sprache für die Abfrage von Datenbanken. Fragen sollten Codebeispiele, Tabellenstruktur, Beispieldaten und ein Tag für die verwendete DBMS-Implementierung (z. B. MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 usw.) enthalten. Wenn sich Ihre Frage nur auf ein bestimmtes DBMS bezieht (verwendet bestimmte Erweiterungen / Funktionen), verwenden Sie stattdessen das Tag des DBMS. Antworten auf mit SQL gekennzeichnete Fragen sollten den ISO / IEC-Standard SQL verwenden. ___ tag123hibernate ___ Hibernate ist eine ORM-Bibliothek (Object-Relational Mapping) für die Sprache Java, die es Entwicklern ermöglicht, POJO-artige Domänenmodelle in ihren Anwendungen zu verwenden, die weit über das Object / Relational Mapping hinausgehen. ___ antwort13799052 ___

Laden Sie alle Postleitzahlen in der Datenbank in eine Liste. Und in der Benutzerliste der eingefügten Zip-Codes machen Sie %code% .

Problem gelöst!

    
___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ tag123postgresql ___ PostgreSQL ist ein Open-Source-Objektrelationales Datenbankverwaltungssystem (ORDBMS), das für alle wichtigen Plattformen einschließlich Linux, UNIX, Windows und OS X verfügbar ist. Bitte geben Sie Ihre genaue Version von Postgres an, wenn Sie Fragen stellen. Fragen zur Administration oder erweiterten Funktionen richten Sie am besten auf dba.stackexchange.com. ___ answer13799785 ___

Angenommen, Sie validieren 1000 Codes gegen eine Tabelle von 100000 Datensätzen, in denen der Code der Primärschlüssel ist und einen Clustered-Index hat.

  • Option A ist keine Verbesserung, Hibernate wird das gleiche SELECT ... IN erstellen ... Sie könnten selbst schreiben.
  • Option B und die aktuelle Abfrage können den Index möglicherweise nicht verwenden.
  • Option D ist möglicherweise gut, wenn Sie sicher sind, dass sich die Postleitzahlen nicht zu beliebigen Zeiten ändern, was unwahrscheinlich ist, oder wenn Sie versuchen, vorhandene Codes zu verarbeiten.
  • Option C (Erstellen einer temporären Tabelle, Ausgabe von 1000 INSERT-Anweisungen und Verbinden von 1000 Zeilen mit 100000 in einem einzigen SELECT) ist nicht wettbewerbsfähig mit der Ausgabe von 1000 einfachen und indexfreundlichen Abfragen für jeweils einen einzelnen neuen Code:

    SELECT COUNT (*) Von Zip WHERE Zip.code =: neuerCode

___
Thihara 10.12.2012 10:26
quelle
0

Angenommen, Sie validieren 1000 Codes gegen eine Tabelle von 100000 Datensätzen, in denen der Code der Primärschlüssel ist und einen Clustered-Index hat.

  • Option A ist keine Verbesserung, Hibernate wird das gleiche SELECT ... IN erstellen ... Sie könnten selbst schreiben.
  • Option B und die aktuelle Abfrage können den Index möglicherweise nicht verwenden.
  • Option D ist möglicherweise gut, wenn Sie sicher sind, dass sich die Postleitzahlen nicht zu beliebigen Zeiten ändern, was unwahrscheinlich ist, oder wenn Sie versuchen, vorhandene Codes zu verarbeiten.
  • Option C (Erstellen einer temporären Tabelle, Ausgabe von 1000 INSERT-Anweisungen und Verbinden von 1000 Zeilen mit 100000 in einem einzigen SELECT) ist nicht wettbewerbsfähig mit der Ausgabe von 1000 einfachen und indexfreundlichen Abfragen für jeweils einen einzelnen neuen Code:

    SELECT COUNT (*) Von Zip WHERE Zip.code =: neuerCode

Lorenzo Gatti 10.12.2012 11:10
quelle
0

Option D:
Laden Sie alle vorhandenen Postleitzahlen aus der Datenbank (Paginierung?) Und machen Sie den Vergleich in Ihrer Anwendung.

Was Ihre Option A betrifft:
Ich erinnere mich an eine Beschränkung der SQL-Abfrage Länge, aber das war auf DB2, ich weiß nicht, ob es eine Beschränkung für PostgreSQL gibt.

    
Kai 10.12.2012 10:23
quelle
0

Es gibt ungefähr 45'000 Postleitzahlen in den USA und die scheinen auf dem neuesten Stand zu sein. Wenn dies ein jährlicher Job ist, schreib es nicht in Java. Erstellen Sie ein SQL-Skript, das die Postleitzahlen in eine neue Tabelle lädt und eine Insert-Anweisung mit

schreibt

insert XXX into zip where zip.code not in (select code from ziptemp)

Lassen Sie Ihre Mitarbeiter dieses zwei Zeilen umfassende SQL-Skript einmal pro Jahr ausführen und kaufen Sie sich das nicht im Java-Code. Plus, wenn Sie dies aus Java heraushalten, können Sie grundsätzlich jede Annäherung angehen, weil es niemanden interessiert, ob das für 30 Minuten in Offpeak-Zeiten läuft.

teile und imperra

    
Stefan 10.12.2012 11:23
quelle
0

Haben Sie versucht, Unterabfragen IN zu verwenden?

Ссылка

wäre so etwas

%Vor%

sry, wenn ich den Code irreführe, es dauert eine Weile, da ich Hibernate nicht verwende

    
fredcrs 10.12.2012 10:27
quelle

Tags und Links