2016-12-15 11 views
0

パフォーマンスのために次のクエリスタイルのほうが適していますか?MySQLのパフォーマンス - LEFT JOIN/HAVINGとサブクエリとの比較

基本的には、関連するレコードをGROUP_CONCATで1行に戻しています。GROUP_CONCAT値で別の結合でフィルタリングする必要があります。さらに、join/group_concats/havingsやsub queriesを順番に追加する必要がありますより関連する値でフィルタリングする。正式にはLEFT JOINのほうが速いのがわかりましたが、GROUP_CONCATとHAVINGがあるかどうかは疑問です。

(これは非常に単純化した例であり、実際のデータは、より多くの属性を持っており、それがDrupalのMySQLのアーキテクチャから読んでいる)

ありがとう!それは使用するインデックス彼ができるを理解するために、オプティマイザを助けるので、JOIN使用

Main Records 
+----+-----------------+----------------+-----------+-----------+ 
| id | other_record_id | value   | type  | attribute | 
+----+-----------------+----------------+-----------+-----------+ 
| 1 |    0 | Red Building | building |   | 
| 2 |    1 | ACME Plumbing | attribute | company | 
| 3 |    1 | east_side  | attribute | location | 
| 4 |    0 | Green Building | building |   | 
| 5 |    4 | AJAX Heating | attribute | company | 
| 6 |    4 | west_side  | attribute | location | 
| 7 |    0 | Blue Building | building |   | 
| 8 |    7 | ZZZ Mattresses | attribute | company | 
| 9 |    7 | south_side  | attribute | location | 
+----+-----------------+----------------+-----------+-----------+ 

location_transaltions 
+-------------+------------+ 
| location_id | value  | 
+-------------+------------+ 
|   1 | east_side | 
|   2 | west_side | 
|   3 | south_side | 
+-------------+------------+ 

locations 
+----+--------------------+ 
| id | name    | 
+----+--------------------+ 
| 1 | Arts District  | 
| 2 | Warehouse District | 
| 3 | Suburb    | 
+----+--------------------+ 

クエリ#1

SELECT 
    a.id, 
    GROUP_CONCAT(
     IF(b.attribute = 'company', b.value, NULL) 
    ) AS company_value, 
    GROUP_CONCAT(
     IF(b.attribute = 'location', b.value, NULL) 
    ) AS location_value, 
    GROUP_CONCAT(
     IF(b.attribute = 'location', lt.location_id, NULL) 
    ) AS location_id  
FROM 
records a 
LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute' 
LEFT JOIN location_translations lt ON lt.value = b.value 
WHERE a.type = 'building' 
GROUP BY a.id 
HAVING location_id = 2 

クエリ#2

SELECT temp.* FROM (
    SELECT 
     a.id, 
     GROUP_CONCAT(
      IF(b.attribute = 'company', b.value, NULL) 
     ) AS company_value, 
     GROUP_CONCAT(
      IF(b.attribute = 'location', b.value, NULL) 
     ) AS location_value 
    FROM 
    records a 
    LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute' 
    WHERE a.type = 'building' 
    GROUP BY a.id 
) as temp 
LEFT JOIN location_translations lt ON lt.value = temp.location_value 
WHERE location_id = 2 

答えて

0

は、ほとんどの場合に好適です。あなたの場合、クエリ#1は十分に見えます。
もちろん、テーブルにインデックスがある場合にのみ機能します。チェック表recordsvalue

idother_record_idvaluetype列、テーブル location_translationsのインデックスを持っています
関連する問題