2017-05-27 1 views
1

Ich versuche, eine Suche nach IP-Adressen eines Clients, dann suchen Sie alle diese IP-Adressen für weitere Clients. Im Grunde versuche ich zu sehen, ob ein Client IP-Adressen mit anderen Clients geteilt hat.Beschleunigen doppelte/verschachtelte Select-Abfrage für IP-Lookups

Das Problem, das ich renne, ist, dass die Abfrage unabhängig von der Datengröße, auf der sie ausgeführt wird, 25-30 Sekunden dauert. Ich habe mich gefragt, ob es eine effektivere Abfrage oder Tabelleneinrichtung gab. Wir haben derzeit über 6.300.000 Zeilen in dieser Tabelle.


Die Abfrage, die ich zur Zeit habe, ist:

select * from client_ip 
where ip in(
    select ip from client_ip 
    where id = "6" and last_login > "2017-04-26" 
) 

Diese Abfrage wird die IP-Adressen für die Client-ID 6 greifen und all diese IPs nachschlagen und die Zeilen aufzuzählen, in denen sie auftreten. Die ausgegebene Auswahlliste ist die IP des Clients und anderer Clients, die auch die gleiche IP haben.

Beispielergebnisse:

Results

Tabelle Ansicht client_ip:

Table view

dieser Tabelle eine neue Zeile mit ihren Benutzer anmeldet id, ip, last_login Datum und die count (wie oft sie in dieser IP waren). Das bedeutet, dass jede IP, die ein Client verwendet hat, protokolliert wird.

Wie oben erwähnt, habe ich mich gefragt, ob es eine effektivere Abfrage oder Tabelleneinrichtung gab, um die Abfragezeit zu beschleunigen.

(Von Kommentar)

CREATE TABLE player_ip (
    id INT(11) NOT NULL, 
    ip VARCHAR(15) NOT NULL, 
    last_login TIMESTAMP NOT NULL 
      DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    count INT(11) NOT NULL, 
    PRIMARY KEY (ip, id), 
    UNIQUE INDEX UNIQUE (ip, id) 
) COLLATE='utf8_general_ci' ENGINE=InnoDB ; 

Jede Hilfe ist willkommen, danke.

+0

Lassen Sie uns zunächst klar werden, was für ein IP ist. Ist es ein gepunkteter Quad (wie 1.2.3.4)? Ist es 131? Ist es 132.224? Ist es 1.0.111? –

+0

Zweitens, zählen Sie dies als ein Match: 216.111.222.33 vs 216.111.9.8? Wenn ja warum? –

+0

Ein gepunkteter Vierer. Übereinstimmungen müssen identisch sein, weil ich sehen möchte, welche Kunden genau welche Adressen geteilt haben. – huhn

Antwort

2

Sind id, ip, last_login, die Spalten in client_ip zählen? Wenn nicht bitte geben Sie SHOW CREATE TABLE client_ip.

SELECT b.id, b.ip, b.last_login, b.count 
    FROM client_ip AS a 
    JOIN client_ip AS b ON a.ip = b.ip 
    WHERE a.id = "6" 
     AND a.last_login >= "2017-04-26"; 

Als allgemeine Regel vermeiden Sie IN (SELECT ...); verwandle es in eine JOIN. (A "Self-Join" in dieser Situation.)

Sie müssen

INDEX(id, last_login) 
INDEX(ip) 

(Die CREATE TABLE wird mir helfen, zu vermeiden mit Ihrem vorhandenen Indizes in Konflikt.)

+0

Dies funktioniert derzeit, ohne meine Indizes zu stören. Gibt die erwarteten Ergebnisse in 1,078 Sekunden im Vergleich zu 24,485 Sekunden mit meiner ursprünglichen Abfrage zurück. – huhn

+0

Ich habe meine CREATE TABLE hier kommentiert: https://stackoverflow.com/questions/44212807/speeding-up-double-nested-select-query-for-ip-lookups#comment75437969_44212807 – huhn

+0

Hinzufügen von 'INDEX (id, last_login)' wird mache es wahrscheinlich noch schneller. –