2016-07-27 10 views
0

テーブルから行を別の列の列として取得するために、結合およびグループ化を使用するクエリを高速化する方法を理解しようとしています。また、having節も使用します。他のテーブルの行を列として選択し、HAVING句を使用するMySQLクエリを最適化する

私は次の2つの表があります取得する

select 
    p.user_id, 
    u.name, 
    max(case when p.type=1 then p.name end) as car, 
    max(case when p.type=2 then p.name end) as computer, 
    max(case when p.type=3 then p.name end) as phone 
from 
    possesions p inner join users u 
    on p.user_id=u.id 
group by 
    p.user_id, 
    u.name 
having 
    car='toyota' 

:私は次のクエリを使用してい

id user_id type_id type  name 
1 1  1  car   honda 
2 1  2  computer mac 
3 2  1  car   toyota 
4 2  2  computer pc 
5 2  3  phone  htc 
6 3  1  car   toyota 
7 3  2  computer pc 
8 3  3  phone  samsung 

ユーザー:

id name 
1 bob 
2 joe 
3 paul 

財産をこの出力として:

user_id name car  computer phone 
2  joe  toyota pc   htc 
3  paul toyota pc   samsung 

相当量のデータがあります - 約75kユーザー、200k possesions、25種類の所有タイプがあります。クエリには約5秒かかります。私は、クエリに説明を行うと、私はこれを取得:

id select_type table  type possible_keys   key     key_len ref    rows  Extra 
1 SIMPLE  users  index (NULL)     PRIMARY    4   (NULL)   77453 Using index 
1 SIMPLE  possesions ref FK_possessions_users FK_possessions_users 4   mydb.users.id 1  

私はすべてのid列に索引を持っています。これをスピードアップするために他に何かがあるかどうか疑問に思うだけです。私がHAVING句を削除すると、それは素早く照明になります。どんな助けでも大歓迎です、ありがとうございます。

答えて

0

これはあなたのクエリです:

select u.id, u.name, 
     max(case when p.type = 1 then p.name end) as car, 
     max(case when p.type = 2 then p.name end) as computer, 
     max(case when p.type = 3 then p.name end) as phone 
from users u join 
    possesions p 
    on p.user_id = u.id 
group by u.id, u.name 
having car = 'toyota'; 

MySQLは基本的に集約クエリを最適化するための機会を提供しています。これをjoinバージョンに変更して、それが機能するかどうかを確認することができます。だから、それぞれのタイプには、最高1回表示されていることを仮定:このため

select u.id, u.name, pc.name as car, pcomp.name as computer, pp.name as phone 
from users u join 
    possesions pc 
    on pc.user_id = u.id and 
     pc.type = 1 and pc.name = 'toyota' left join 
    possessions pcomp 
    on pcomp.user_id = u.id and pcomp.type = 2 left join 
    possessions pp 
    on pp.user_id = u.id and pp.type = 3; 

を、あなたはpc(user_id, type, name)にインデックスをしたいです。

注:クエリの節約は、group byでの集計を避けることです。特定の型に複数の名前がある場合は、とにかく集計する必要があります。

関連する問題