簡體   English   中英

MySQL性能-LEFT JOIN / HAVING與子查詢

[英]MySQL Performance - LEFT JOIN / HAVING vs Sub Query

下列哪種查詢風格對性能更好?

基本上,我使用GROUP_CONCAT將許多相關記錄返回到一行,並且需要根據GROUP_CONCAT值對另一個聯接進行過濾,並且我需要添加更多的joins / group_concats / havings或子查詢,以便按更多過濾條件相關值。 我正式看到LEFT JOIN更快,但是我想知道GROUP_CONCAT和HAVING是否通過了。

(這是一個非常簡化的示例,實際數據具有更多屬性,並且它是從Drupal MySQL體系結構讀取的)

謝謝!

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

在大多數情況下,最好使用JOIN,因為它有助於優化器了解他可以使用哪些索引。 在您的情況下,查詢1看起來足夠好。
當然,它僅在表具有索引時才有效。 檢查表recordsidother_record_idvaluetype列上具有索引,在valuevaluelocation_translations

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM