2016-07-04 7 views
0

私のモデルには2つのテーブルが含まれているとしましょう:人物と住所。 1人はO、1つ以上のアドレスを持つことができます。私はすべての人をリストするクエリを実行しようとしており、それぞれが持っているアドレスの数が含まれています。ここで私はそれを達成するために持っている2つのクエリです:ネストされたオブジェクトをカウントするためにサブクエリを結合する

SELECT 
    persons.*, 
    count(addresses.id) AS number_of_addresses 
FROM `persons` 
    LEFT JOIN addresses ON persons.id = addresses.person_id 
GROUP BY persons.id 

SELECT 
    persons.*, 
    (SELECT COUNT(*) 
    FROM addresses 
    WHERE addresses.person_id = persons.id) AS number_of_addresses 
FROM `persons` 

は、もう1つは、パフォーマンスの期間に他よりも優れている場合、私は思っていました。

+0

この 'cube_models'テーブルは何ですか、なぜ2番目のクエリにのみ表示されますか? 2番目のクエリでは、相関サブクエリが使用されます。通常、結合を使用する同様のクエリよりも実行速度が遅くなりがちです。 –

+1

私は最初のものがより速くなると信じていますが、それらは非常に似ています。両方の実行計画を実行し、その違いを確認してください。私はそれを行うより良い方法があるとは思わない。 – sagi

+0

私はcube_modelsを修正しました。 – TrexXx

答えて

0

パフォーマンス特性を判断する方法は、実際にクエリを実行し、どちらが良いかを確認することです。

インデックスがない場合は、最初の方が良いでしょう。もしあなたがaddresses(person_id)にインデックスを持っているなら、おそらく2番目の方が良いでしょう。

理由は少し複雑です。基本的な理由は、group by(MySQL版)はソートを使用しているからです。そして、種類は複雑さにおいてO(n * log(n))である。したがって、ソートを行う時間はデータよりも速くなります(それほど高速ではなく、少し速い)。その結果、各個人の集まりの集まりは、すべてのデータにわたる個人の集約よりも速くなります。

これは概念です。実際には、MySQLは相関サブクエリのインデックスを使用するため、インデックスを使用しないgroup by全体よりも高速なことがよくあります。

0

私は最初のクエリが最適であり、テーブル構造を変更することでより多くの最適化を提供できると思います。たとえば、person_idフィールドとaddress_idフィールドの両方を定義する(順序は重要です)、アドレステーブルの主キーとして、より高速に結合します。

mysqlテーブルの格納構造は、主キー索引が結合操作で通常の索引よりも非常に高速になるように、索引構成表(クラスター索引)です。

+0

'persons.id'、' addresses.id'と 'addresses.person_id'は全てインデックスを持っています – TrexXx

+0

@TrexXx、mysqlテーブルのストレージ構造は索引構成表(クラスタ化されている)キー索引は通常、結合操作で通常の索引よりも非常に高速です。 –

関連する問題