2017-02-24 3 views
0

私は数年後にmysqlに戻り、問題に遭遇しました。私は動作するクエリを持っていますが、最適化の方法が分かりません。ここでmysqlのクエリデータを制限する

はクエリです:

select 
    u.id as 'User', 
    count(distinct tr.id) as Trips, 
    count(distinct ti.id) as 'Trip Items' 
from 
    users u 
inner join 
    user_emails ue on u.id = ue.user_id 
inner join 
    trips tr on tr.user_id = u.id 
inner join 
    trip_items ti on ti.trip_id = tr.id 
where 
    ue.verified = true and ue.is_primary = true 
and 
    tr.created_at between '2017-02-01 00:00:00' and '2017-02-01 00:59:59' 
group by 1 
having Trips < 30 

私は基本的にだけ与えられた日付範囲の30回の以下の旅行を持っているユーザーのために...すべての旅行や出張のアイテムの数を取得する必要があります。今私はユーザーによって結果をグループ化して、それを実行しています。私は非インデックスフィールド(created_at)の何百万もの結果を見ています。理想的には、私はちょうど合計行程と合計旅行項目を持っている1行戻って取得したいと思います。しかし、クエリ中に「30回未満の旅行」ユーザーをまだ適用しています。これは可能ですか? :)

私は他の解決策を見てみましたが、私が探しているものは少し失われています。私は解決策を探しているわけではありません。たぶん "これをチェックして試してみてください"。

答えて

1

count(distinct)は高額になる可能性があります。 joinを実行する前にを集計してからを実行してください。私は次の作品を考える(これは項目が異なるの旅行の間で共有されていないことを前提としてい):そこにいくつかの問題があると私はそれらを解決することができませんでしたよう

select u.id as `User`, tr.Trips, tr.items 
from users u inner join 
    user_emails ue 
    on u.id = ue.user_id inner join 
    (select tr.user_id, count(*) as Trips, sum(items) as items 
     from trips tr join 
      (select ti.trip_id, count(*) as items 
      from trip_items ti 
      group by ti.trip_id 
      ) ti 
      on ti.trip_id = tr.id 
     where tr.created_at >= '2017-02-01' and tr.created_at < '2017-02-01 01:00:00' 
     group by tr.user_id 
     having trips < 30 
    ) tr 
    on tr.user_id = u.id inner join 
where ue.verified = true and ue.is_primary = true 
group by 1 
+0

が、私はこの碁を与えてみました、それが見えます!これはユーザーが結果を返すようです。だから "User | Trips | TripItems" - 私はちょうど "Trips | TripItems"としてデータを取り戻す方法を見つけようとしていますが、それでも30人以下の旅行制限を各ユーザーに適用しています。私はこれで元気にしようとしていますが、私はそれがどこにあるのかを見ることができますか? – LushJ