2017-06-16 1 views
2

この質問がダムの場合は、事前にお詫び申し上げます。普通の結合を追加すると、クエリ時間が7秒から40秒に低下します。何か不足していますか?

だから私は調査の結果に大きなテーブルがあります。

表調査(120million行):
       ポイント(TINYINT(1))
       質問(VARCHAR( 13))
        CityID(SMALLINT(3))インデックス
        PERSONID(VARCHAR(13))
       自動インクリメント(INT(7))PK

それからはるかに小さいルックアップテーブルを有する:

表city_lookup(< 1000行)
        CityID(SMALLINT(3))PK
       市(VARCHAR(13))

私が行う場合:

select sum(Points), CityID 
from Survey 
where CityID = 256 
group by CityID 

クエリが1行を返し、7秒

を取るしかし、私は行った場合:

select sum(Points), City 
from Survey 
inner join city_lookup on Survey.CityID = city_lookup.CityID 
where Survey.CityID = 256 
group by City 

それでも1行を返すクエリには40秒かかります。

集計されたクエリが実行された後、つまりサブクエリにメインクエリを配置した後に結合が行われるようなクエリを調整すると、7秒間表示されますが、これを行うには、私は最適化のいくつかの明白なステップが欠けていますか?

+0

私は7秒は遅いですが、120million行があります知っている私は、あなたが最初に集約して、参加をお勧めします。私はなぜ結合がそれを非常に遅くするかについて何かを見逃しているかどうか不安です。 – user7253130

+0

ああ、私もちょうどそれを見ましたが、決して気にしないでください! – Tomalak

答えて

2

DBMSは、おそらく集計前1.2億行を結合します。

select c.city, s.sum_points 
from city_lookup c 
join 
(
    select sum(Points) as sum_points, CityID 
    from Survey 
    where CityID = 256 
    group by CityID 
) s on s.cityid = c.cityid; 

が、私はこのために、次のインデックスを作成したい::

CREATE idx ON survey(cityid, points); 
+0

インデックスについての良い点! – Tomalak

2

これが高速であれば、あなたのDBのセットアップについて何もを知っていない:

select sum(Points), CityID 
from Survey 
where CityID = 256 
group by CityID 

、これは速いだけでなく次のようになります。

select 
    s.CityID, s.SumPoints, c.City 
from 
    (
    select sum(Points) SumPoints, CityID 
    from Survey 
    where CityID = 256 
    group by CityID 
) s 
    inner join city_lookup c ON c.CityID = s.CityID 
関連する問題