2013-04-19 2 views
5

Ich habe zwei Tabellen: gpnxuser und key_valueMySQL Abfrage mit JOIN und GROUP BY Optimierung. Ist es möglich?

mysql> describe gpnxuser; 
+--------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+--------------+------+-----+---------+----------------+ 
| id   | bigint(20) | NO | PRI | NULL | auto_increment | 
| version  | bigint(20) | NO |  | NULL |    | 
| email  | varchar(255) | YES |  | NULL |    | 
| uuid   | varchar(255) | NO | MUL | NULL |    | 
| partner_id | bigint(20) | NO | MUL | NULL |    | 
| password  | varchar(255) | YES |  | NULL |    | 
| date_created | datetime  | YES |  | NULL |    | 
| last_updated | datetime  | YES |  | NULL |    | 
+--------------+--------------+------+-----+---------+----------------+ 

und

mysql> describe key_value; 
+----------------+--------------+------+-----+---------+----------------+ 
| Field   | Type   | Null | Key | Default | Extra   | 
+----------------+--------------+------+-----+---------+----------------+ 
| id    | bigint(20) | NO | PRI | NULL | auto_increment | 
| version  | bigint(20) | NO |  | NULL |    | 
| date_created | datetime  | YES |  | NULL |    | 
| last_updated | datetime  | YES |  | NULL |    | 
| upkey   | varchar(255) | NO | MUL | NULL |    | 
| user_id  | bigint(20) | YES | MUL | NULL |    | 
| security_level | int(11)  | NO |  | NULL |    | 
+----------------+--------------+------+-----+---------+----------------+ 

key_value.user_id ist FK dass Referenzen gpnxuser.id. Ich habe auch einen Index in gpnxuser.partner_id, der ein FK ist, der auf eine Tabelle verweist, die "Partner" genannt wird (was meiner Meinung nach für diese Frage keine Rolle spielt).

Für partner_id = 64, habe ich 500K Zeilen in gpnxuser, die Beziehung mit ca. 6M Zeilen in key_value haben.

Ich wollte eine Abfrage haben, die alle unterschiedliche 'key_value.upkey' für die Zugehörigkeit des Benutzers zu einem bestimmten Partner zurückgegeben. Ich habe etwas in der Art:

select upkey from gpnxuser join key_value on gpnxuser.id=key_value.user_id where partner_id=64 group by upkey; 

, die für immer dauert zu laufen. Die Erklärung für die Abfrage wie folgt aussieht:

mysql> explain select upkey from gpnxuser join key_value on gpnxuser.id=key_value.user_id where partner_id=64 group by upkey; 

    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+ 
    | id | select_type | table  | type | possible_keys    | key    | key_len | ref       | rows | Extra          | 
    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+ 
    | 1 | SIMPLE  | gpnxuser | ref | PRIMARY,FKB2D9FEBE725C505E | FKB2D9FEBE725C505E | 8  | const      | 259640 | Using index; Using temporary; Using filesort | 
    | 1 | SIMPLE  | key_value | ref | FK9E0C0F912D11F5A9   | FK9E0C0F912D11F5A9 | 9  | gpnx_finance_db.gpnxuser.id |  14 | Using where         | 
    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+ 

Meine Frage ist: Gibt es eine Abfrage, die schnell laufen kann und erhält das Ergebnis, das ich will?

+0

Es sieht aus wie der beste Ort für diese Frage lautet: http://dba.stackexchange.com/ –

Antwort

1

, was Sie tun müssen, ist verwenden VORHANDEN Aussage: Dies ist nur teilweise Tabellenscan verursacht, bis eine Übereinstimmung gefunden und nicht mehr.

select upkey from (select distinct upkey from key_value) upk 
where EXISTS 
    (select 1 from gpnxuser u, key_value kv 
    where u.id=kv.user_id and partner_id=1 and kv.upkey = upk.upkey) 

NB. In der ursprünglichen Abfrage wird Gruppe von missbraucht: distinct sieht dort besser aus.

select DISTINCT upkey from gpnxuser join key_value on 
gpnxuser.id=key_value.user_id where partner_id=1 
+0

Awesome, funktioniert perfekt! –