2017-08-10 2 views
0

Ich verwende derzeit MySQL Connector/Python, um eine Datenbank abzufragen.MySQL führt mehrere, ähnliche Select-Abfragen mit einer Anweisung aus

Derzeit einer der Prozesse Ich tue das sieht so etwas wie:

SELECT some_column FROM some_table WHERE some_column_2 = foo_1; 
SELECT some_column FROM some_table WHERE some_column_2 = foo_2; 
SELECT some_column FROM some_table WHERE some_column_2 = foo_3; 
... 
SELECT some_column FROM some_table WHERE some_column_2 = foo_9999; 
SELECT some_column FROM some_table WHERE some_column_2 = foo_10000; 

ich eine sehr große Anzahl von sehr ähnlichen Anfragen leite.

Die einzelnen Ergebnisse jeder Abfrage sind wichtig. Selbst wenn eine gegebene Abfrage nichts als Ergebnis ergibt.

Leider ist der aktuelle Ansatz, mehrere tausend Abfragen zu erstellen, zeitraubend und äußerst ineffizient.

Also meine Frage ist: gibt es eine Möglichkeit, diese Prozedur in einer einzigen Abfrage zu verdichten, so dass es effizienter läuft?

Ich denke, das sollte in MySQL definitiv möglich sein, und ich bin mir ziemlich sicher, dass mir etwas fehlt.


Bisher habe ich versucht, den Einsatz von MySQL Connector/Python executemany() Funktion, etwa so:

cursor.executemany("SELECT some_column FROM some_table WHERE some_column_2 = %s", foo_list) 

ich dies eine Liste der Ergebnisse jeder einzelnen Abfrage erhalten erwartet, aber optimiert so viele Anfragen. Leider scheint dies in MySQL Connector/Python nicht zu funktionieren und führt zu einem Syntaxfehler.

Ich vermute, dass Executemany nicht mit SELECT-Anweisungen, nur mit INSERT-Anweisungen verwendet werden soll.


Ich habe gesucht auch im Internet nach Möglichkeiten, Massenabfragen wählen auszuführen, aber ich habe noch nichts Relevantes zu meiner Situation zu finden.

Ich mag ausdrücklich würde darauf hinweisen, dass

SELECT some_column FROM some_table WHERE some_column_2 IN (foo_1, foo_2, foo_3, etc); 

nicht eine gültige Lösung ist, weil es die Ergebnisse nicht erhalten (oder dessen Fehlen) von jeder einzelnen Abfrage.


Jede Unterstützung mit diesem wäre willkommen.

+0

Ja, etwas effizienter wird effizienter sein. – Strawberry

+0

Siehe [Warum sollte ich ein MCVE für eine scheinbar sehr einfache SQL-Abfrage bereitstellen] (http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for -was-scheint-mir-zu-sehr-einfach-sql-query) – Strawberry

+0

Warum holen Sie nicht auch 'some_column_2' mit der einzelnen SELECT-Abfrage und ordnen Sie explizit die (mit dict)" some_column_2 "mit der Entsprechende "some_column"? –

Antwort

1

Anstatt

SELECT FROM some_column some_table WHERE some_column_2 IN (foo_1, foo_2, ..., foo_N);

einfach fragen Sie nach

SELECT some_column, some_column_2 FROM some_table WHERE some_column_2 IN (foo_1, foo_2, ..., foo_N); 

Der Code der Abfrage kennt die foo 1..N Werte zu erzeugen, und wird eine Teilmenge von ihnen kommen zurück in die Spalte 2 Ergebnis.

Als separate Angelegenheit ist die Verwendung von IN oft ein Anti-Pattern, das die Fähigkeit des mysql-Optimizers stört, einen guten Plan zu erstellen.Für eine große IN-Klausel, stellen Sie möglicherweise fest, dass es besser ist, sich die Mühe zu machen, eine FOO-Tabelle zu füllen und dagegen anzutreten.

+0

Ich habe beschlossen, eine neue Tabelle zu erstellen und eine JOIN-Anweisung zu verwenden. Dies scheint die beste verfügbare Vorgehensweise zu sein. Danke, dass du mich in die richtige Richtung gelenkt hast (ich bin ziemlich neu in MySQL). –

0

Ich habe die Antwort von J H akzeptiert, weil sie die Information lieferte, nach der ich gesucht habe. Jedoch werde ich dies auch als eine spezifische Implementierung von dem, was sie vorgeschlagen haben:

cursor.execute("CREATE TABLE foo_table (foo VARCHAR(20))") 
insert_query = "INSERT INTO foo_table (foo) VALUES (%s)" 
cursor.executemany(insert_query, foo_list) 
select_query = "SELECT some_table.some_column FROM some_table RIGHT JOIN foo_table on some_table.foo = foo_table.foo GROUP BY 1" 
cursor.execute(select_query) 

Dies scheint so zu funktionieren, wie vorgesehen.

EDIT: Da das Cursor-Objekt in Python MySQL Connector/Python aus irgendeinem Grund einfach "Null" -Werte weglassen wird, ist es immer noch notwendig, "Some_column" und "Foo" Werte zu paaren. Da in meinem Fall jeder "some_column" -Wert für jeden "foo" -Wert immer vollständig eindeutig ist, kann ich ANY_VALUE() dazu verwenden.

+0

Die 'group by 1' ist ein wenig seltsam, ich denke, es funktioniert nach' group by some_column', von dem ich hoffte, dass es einen eindeutigen Index oder zumindest einen Index hatte. –

+1

Ich empfehle dringend ein PK: 'CREATE TABLE foo_table (foo VARCHAR (20) Primärschlüssel)'. Im Allgemeinen sollte jede Relation einen Primärschlüssel haben, auch wenn es sich um einen zusammengesetzten Schlüssel handelt, der einige Spalten umfasst. Für diesen speziellen JOIN-Wert möchten Sie wirklich, dass der Optimierer einen eindeutigen Index ausnutzt, wenn er bestimmt, welche die treibende Tabelle ist. Verwenden Sie EXPLAIN, um zu überprüfen, ob Ihre Join-Klauseln sinnvoll sind. (https://www.sitepoint.com/using-explain-to-write-better-mysql-queries/) –

+0

Die Verwendung eines Primärschlüssels ist besser in Bezug auf die Optimierung? Gut zu wissen, danke. Ich bin mit MySQL nicht sehr vertraut. –

Verwandte Themen