2013-04-19 25 views
5

Tôi có hai bảng: gpnxuser và key_valueTruy vấn MySQL với JOIN và GROUP BY tối ưu hóa. Có thể không?

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 |    | 
+--------------+--------------+------+-----+---------+----------------+ 

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 là FK rằng tài liệu tham khảo gpnxuser.id. Tôi cũng có một chỉ mục trong gpnxuser.partner_id là một FK tham khảo một bảng gọi là "đối tác" (mà, tôi nghĩ, không quan trọng nhiều đến câu hỏi này).

Đối với partner_id = 64, tôi có 500 nghìn hàng trong gpnxuser có mối quan hệ với các hàng 6M xấp xỉ 6M trong key_value.

Tôi muốn có truy vấn trả về tất cả 'key_value.upkey' riêng biệt cho người dùng thuộc về một đối tác nhất định. Tôi đã làm một việc như sau:

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

chạy mãi mãi. Giải thích cho truy vấn trông giống như:

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         | 
    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+ 

Câu hỏi của tôi là: có truy vấn nào có thể chạy nhanh và đạt được kết quả tôi muốn không?

+0

Có vẻ như nơi tốt nhất cho câu hỏi này là: http://dba.stackexchange.com/ –

Trả lời

1

những gì bạn cần làm là sử dụng EXISTS tuyên bố: Điều này sẽ gây ra chỉ một phần bảng quét cho đến khi một trận đấu tìm thấy và không hơn.

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. Trong truy vấn ban đầu, nhóm theo bị lạm dụng: riêng biệt trông đẹp hơn ở đó.

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

Tuyệt vời, hoạt động hoàn hảo! –