【问题标题】:MySQL Performance - LEFT JOIN / HAVING vs Sub QueryMySQL 性能 - LEFT JOIN / HAVING 与子查询
【发布时间】:2016-12-16 02:15:13
【问题描述】:

以下哪种查询样式对性能更好?

基本上,我使用 GROUP_CONCAT 将许多相关记录返回到一行中,并且我需要通过 GROUP_CONCAT 值上的另一个联接进行过滤,并且我需要添加更多联接/group_concats/haves 或子查询,以便按更多相关值过滤。我看到,正式地,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

【问题讨论】:

    标签: mysql drupal


    【解决方案1】:

    在大多数情况下,最好使用 JOIN,因为它有助于优化器了解他可以使用哪些索引。在您的情况下,查询 #1 看起来已经足够好了。
    当然,它只有在表有索引时才有效。检查表recordsidother_record_idvaluetype 列上有索引,表location_translationsvalue 上有索引

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      • 2018-12-24
      • 2015-02-22
      • 2012-09-05
      • 1970-01-01
      • 2013-04-07
      相关资源
      最近更新 更多