2017-09-30 1 views
0

Ich habe einige Daten zu überprüfen, jedoch renne ich in einen Roadblock mit einer Abfrage, die nicht zurückkehrt. Was kann ich hier anders machen, da ich wirklich nicht verstehe, dass diese Abfragen zurückkommen (ausgeführt von mysql workbench), selbst nachdem sie mehrere Stunden laufen gelassen wurden? Bin ich gerade unterversorgt?Google Cloud SQL, das Zeilen auswählt, die in einer anderen Tabelle nicht vorhanden sind

Ich habe eine n1-Standard 4 Google Cloud Sql-Instanz (4cpu, 15GB RAM). Die zwei Tabellen sind unten. Es gibt auch einen Index für customer_id für Tabelle 1. Tabelle 2 hat 885481 Zeilen und Tabelle 1 hat 1891653 Zeilen.

Ich habe versucht, drei Varianten einer Abfrage nach Kunden-IDs in Tabelle 1 zu suchen, wo sie in Tabelle 2 nicht vorhanden sind (dargestellt als account_group_id).

Was ich erwartet hätte sein performante und tatsächlich zurück:

Select customer_id 
FROM Table1 as a 
WHERE NOT EXISTS(
    Select account_group_id 
    FROM Table2 as b WHERE b.account_group_id = a.customer_id 
) 

Als Sub-Abfrage:

Select customer_id 
FROM Table1 
WHERE customer_id NOT IN(
    Select account_group_id 
    FROM Table2 
) 

Als LEFT JOIN:

SELECT customer_id 
FROM Table1 as a 
LEFT OUTER JOIN Table2 as b ON a.customer_id = b.account_group_id 
WHERE b.account_group_id IS NULL 

EDIT: Also nach etwas Basteln und tatsächlich mit EXPLAIN vor dem Posten meiner Frage, die Tabelle2 Subq UI führt aus irgendeinem Grund einen FULL TABLE-Scan durch. Ich habe diese Abfrage in meinen Test-/Staging-Umgebungen mit den gleichen Indexpattern ausprobiert, und ich sehe einen Index, der dort sucht. Jetzt bin ich noch mehr verwirrt. full table scan

Auch wenn ich einen Force-Index-Hinweis hinzufüge, lehnt der Abfrageoptimierer die Verwendung des Primärschlüssels ab.

Dies ist, was der Abfrage-Plan wie auf meiner Staging-Umgebung aussieht:

enter image description here

Irgendwelche Gedanken darüber, warum dies auftritt?

Tabelle 1:

Table 1

Tabelle 2:

Table 2

+0

in der dritten Variante Sie links benötigen beitreten – soft87

Antwort

0

Nun, nachdem viel Bastelei existiert ich komplett überarbeitet diese Abfrage der dumme Optimierer den Index Ich wollte verwenden zu machen ...mit der Größe der Tabellen zu tun, muss etwas sein:

SELECT a.customer_id 
FROM Table1 as a 
WHERE a.customer_id NOT IN (
    SELECT b.customer_id 
    FROM Table1 as b 
    JOIN (select account_group_id from Table2) as x on x.account_group_id = b.customer_id 
) 
2

Zwei Dinge:

  1. Stellen Sie sicher, Tabelle 2 einen Index für account_group_id hat. Andernfalls führen Sie einen vollständigen Tabellenscan durch, der nicht effizient ist.

  2. Die Option SUB QUERY ist die bessere Wette, aber nicht OUTER JOIN, da sie beide Tabellenzeilen multipliziert und ein schreckliches (und scheinbar nie endendes!) Ergebnis erzielt.

Wenn der Index nicht

-- CREATING AN INDEX IN CASE 
CREATE INDEX T2_agi ON Table2(account_group_id);  

SELECT customer_id 
FROM Table1 as a 
WHERE customer_id NOT IN(
    Select account_group_id 
    FROM Table2 
); 
+0

Danke, werde ich versuchen. Es gibt keinen Index für die account_group_id, aber das ist der Primärschlüssel. Ich habe hier vielleicht ein Missverständnis, da ich wusste, dass der Primärschlüssel dies erfüllen würde. – Jesse

+0

Ja, der 'PRIMARY KEY' ist eigentlich der beste' INDEX'. Versuchen Sie eine EXPLAIN in der Abfrage. Die Syntax ist im Grunde das Wort "EXPLAIN" vor der Abfrage stecken! –

+0

Danke für die Hilfe. Ich hätte es erklären sollen, bevor ich meine Frage gepostet habe. Es ist ziemlich klar, dass der primäre Index aus irgendeinem Grund in der Unterabfrage gemäß meinen Änderungen ignoriert wird. Irgendwelche Gedanken als auch was zu versuchen? – Jesse

Verwandte Themen