【问题标题】:Left Join on Subquery with criteria in MySQL alternative?使用 MySQL 替代方案中的条件在子查询上左连接?
【发布时间】:2011-10-24 05:07:15
【问题描述】:
SELECT a.tag,CONCAT(u.first_name,' ',u.last_name)
FROM assets a   
LEFT JOIN (SELECT asset_id,assigned_to_id
       FROM asset_activity
       WHERE assigned IN (SELECT MAX(assigned)
                          FROM asset_activity
                          GROUP BY asset_id)) 
       v ON v.asset_id = a.id
LEFT JOIN users u ON v.assigned_to_id = u.id  
WHERE ($1 IS NULL OR u.last_name LIKE $1)     

由于 MySQL 在子查询上的左连接性能非常糟糕,我需要找到一些其他方法来做到这一点。我可以通过选择中的子查询来选择我需要的内容,但它必须是有条件的。它应该只返回与 LIKE 匹配的记录,并且对于子查询,它仍会从资产中返回一条为 assignment_to 为空值的记录,所以我不能这样做。

执行计划:

id select_type        table          type     possible_keys  key     key_len  ref  rows              Extra    
1  PRIMARY            a              ALL      null           null     null    null             1,447
1  PRIMARY            <derived2>     ALL      null           null     null    null             1,396
1  PRIMARY            u              eq_ref   PRIMARY        PRIMARY  4       v.assigned_to_id 1 
2  DERIVED            asset_activity ALL      null           null     null    null             1,400 Using where 
3  DEPENDENT SUBQUERY asset_activity index    null           asset_id 4       null             1,400 Using filesort

索引:

Table   Non_unique        Key_name  Seq_in_index      Column_name       Collation Cardinality Sub_part Packed   Null  Index_type    Comment
assets  0                 PRIMARY   1                 id                A         144         ""                       BTREE       ""    
assets  1                 serial    1                 serial            A         1447                          YES    BTREE       ""
assets  1                 serial    2                 cal_num           A         1447                          YES    BTREE       ""

Table          Non_unique Key_name          Seq_in_index Column_name       Collation Cardinality Sub_part Packed Null Index_type Comment
asset_activity 0          PRIMARY           1            id                A         1400        ""                   BTREE      ""
asset_activity 1          asset_id          1            asset_id          A                     ""                   BTREE      ""
asset_activity 1          location_id       1            location_id       A                                     YES  BTREE      ""
asset_activity 1          assigned_to_id    1            assigned_to_id    A                                     YES  BTREE      ""
asset_activity 1          assigned_to_table 1            assigned_to_table A                                     YES  BTREE      ""
asset_activity 1          created           1            created           A                     ""                   BTREE      ""

【问题讨论】:

标签: mysql join conditional subquery


【解决方案1】:

好的,这就是我最终实现它的方式:

SELECT a.tag,CONCAT(u.first_name,' ',u.last_name) 
FROM assets a    
LEFT JOIN asset_activity v ON v.asset_id = a.id
LEFT JOIN asset_activity v2 ON v2.asset_id = a.id 
     AND (v.assigned < v2.assigned OR v.assigned = v2.assigned AND v.id < v2.id)
LEFT JOIN users u ON v.assigned_to_id = u.id               
WHERE v2.id IS NULL
  AND ($1 IS NULL OR u.last_name LIKE $1)

这比在带有子查询的子查询上执行的左连接要好得多。 .0064 秒,而其他方法为 5 秒或更多,当将其绑定到我的代码中的网格、分页等时,它变成了更多。

【讨论】:

    猜你喜欢
    • 2020-02-14
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2011-03-12
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多