【问题标题】:select last record in sub query选择子查询中的最后一条记录
【发布时间】:2015-02-12 17:47:20
【问题描述】:

已阅读所有类似的 qs 但无法应用于我的 sql

想要选择所有客户和最后插入的操作记录。 下面的 sql 首先选择最大 actionid,然后在另一个子查询中使用它 - 这需要 5+ 秒才能运行;(

请告知TQ

SELECT cus.cusid,cus.FirstName,cus.Surname,
       lastact.actionid, lastact.actiondate, lastact.siteid
FROM cus 
    LEFT JOIN(
        SELECT MAX(actionid) AS maxactionid, cusid
        FROM `action`
        INNER JOIN `event` ON event.eventid = action.`eventid`
        GROUP BY cusid
    ) AS maxactionid ON maxactionid.cusid = cus.cusid
    LEFT JOIN (
    SELECT 
    action.actionid,
    action.actiondate,
    event.cusid,
    event.siteid 
    FROM
      `action` 
      INNER JOIN `event` 
        ON event.eventid = action.eventid 
    ORDER BY actionid DESC
    ) AS lastact ON lastact.actionid = maxactionid 
WHERE UCASE(CONCAT(firstname, surname)) LIKE '%JIM%HEMM%'

TQ 的想法 - 请参阅以下内容:

1) 限制思想,为 lastact.actionid、lastact.actiondate、lastact.siteid 提供空结果 - 但运行时间为 0.075 秒! 可惜这个想法失败了

SELECT cus.cusid,cus.FirstName,cus.Surname, lastact.actionid, lastact.actiondate, lastact.siteid 
FROM cus 
LEFT JOIN (SELECT action.actionid, action.actiondate, event.cusid, event.siteid 
FROM action 
INNER JOIN event ON event.eventid = action.eventid 
ORDER BY actionid DESC LIMIT 1 
) AS lastact ON lastact.cusid = cus.cusid 
WHERE UCASE(CONCAT(firstname, surname)) LIKE '%JIM%HEMM%' 

2) EXPLAIN 原始查询结果为:

3) 添加 LIKE 'JIM%' AND cus.surname LIKE 'HEMM%' 不会对查询时间产生太大影响,但会根据建议添加

您好 - 使用大家的想法取得了很好的结果 - 谢谢

1) 将 WHERE 更改为 cus.FirstName LIKE 'JIM%' AND cus.surname LIKE 'H%'

2) 添加了名、姓索引

3) 在动作表中添加了 cusid(不再需要事件表)

4) 将查找表(不在原始问题中)移到操作子查询之外

完成的 sql 看起来像(在 0.063 秒内运行 - 用只有一个字母的姓氏测试!)

SELECT cus.cusid,cus.FirstName,cus.Surname, lastact.actionid, lastact.actiondate, lastact.siteid, actiontype.action,
FROM cus 
LEFT JOIN (
    SELECT action.actionid, action.actiondate, event.cusid, event.siteid 
    FROM action  
    ORDER BY actionid DESC
) AS lastact ON lastact.cusid = cus.cusid
LEFT JOIN actiontype ON actiontype.actiontypeid = lastact.typeid 
WHERE cus.FirstName LIKE 'JIM%' AND cus.surname LIKE 'H%'
GROUP BY lastact.cusid  

【问题讨论】:

  • 如果将select MAX(actionid) 更改为select actionid 并添加limit 1order by desc 会怎样
  • 如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 DDL(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
  • 我会先运行一个 EXPLAIN 来看看计划者想要做什么。我怀疑这是对连接字符串的(不可索引)搜索
  • 第三点应该有帮助,您是否创建了“名字”和“姓氏”的索引?

标签: mysql


【解决方案1】:
  • 正如 JC Sama 所说“通过选择 actionid 更改选择 MAX(actionid) 并添加限制 1 并按 desc 排序”,有助于索引 搜索。
  • 正如 David K-J 所说,“首先运行 EXPLAIN 以查看规划器正在尝试做什么。我怀疑这是对连接字符串的(不可索引的)搜索”。
  • 在比较时,不应将小丑 '%' 放在字符串的开头,这会禁用索引搜索。
  • 在比较时不应使用函数(至少,尽可能避免使用),索引搜索也是如此。
  • 现在您可以使用索引了,如果您还没有使用,请添加它们。
  • 我在这里可能错了,但就我而言,我看不到最后一个 LEFT JOIN 的意义。您可以从第一个 LEFT JOIN 中提取该数据。也不是,你为什么不按 cusid 分组。

总而言之,我做的sql是(显然没有测试,你可能需要修复一些东西):

SELECT cus.cusid,cus.FirstName,cus.Surname,
maxaction.actionid, maxaction.actiondate, maxaction.siteid
FROM cus 
LEFT JOIN(
    SELECT actionid AS maxaction, action.actiondate, event.cusid, event.siteid
    FROM `action`
    INNER JOIN `event` ON event.eventid = action.eventid
    order by actionid desc limit 1
) AS maxaction ON maxaction.cusid = cus.cusid
WHERE cus.FirstName like 'JIM%' and cus.surname like 'HEMM%'

【讨论】:

    猜你喜欢
    • 2015-07-24
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多