繁体   English   中英

查询效率(多项选择)

[英]Query efficiency (multiple selects)

我有两个表-一个称为customer_records ,另一个称为customer_actions

customer_records具有以下架构:

CustomerID (auto increment, primary key)
CustomerName
...etc...

customer_actions具有以下架构:

ActionID (auto increment, primary key)
CustomerID (relates to customer_records)
ActionType
ActionTime (UNIX time stamp that the entry was made)
Note (TEXT type)

每一个用户执行一个客户记录的动作时,一个条目是由customer_actions ,并给予用户输入一个音符的机会。 ActionType可以是几个值之一(例如“指定更新”或“添加的案例信息”-只能是选项列表之一)。

我想要做的是显示一个来自customer_records的记录列表,其中最后一个ActionType是某个值。

到目前为止,我已经搜索了网络/ SO并提出了这个怪物:

SELECT * FROM (
    SELECT * FROM (
        SELECT * FROM `customer_actions` ORDER BY `EntryID` DESC
    ) list1 GROUP BY `CustomerID`
) list2 WHERE `ActionType`='whatever' LIMIT 0,30

很棒-它列出了每个客户ID及其最后的操作。 但是查询有时非常慢(请注意: customer_records有近20,000条记录)。 谁能提供任何提示,说明如何解决查询中的这个怪问题或调整表格以提供更快的结果? 我正在使用MySQL。 非常感谢您的任何帮助。

编辑:明确地说,我需要查看上一个操作是“无论如何”的客户列表。

要按客户的最后操作来过滤客户,您可以使用相关子查询...

SELECT
  *
FROM
  customer_records
INNER JOIN
  customer_actions
    ON  customer_actions.CustomerID = customer_records.CustomerID
    AND customer_actions.ActionDate = (
           SELECT
             MAX(ActionDate)
           FROM
             customer_actions  AS lookup
           WHERE
             CustomerID = customer_records.CustomerID
        )
WHERE
  customer_actions.ActionType = 'Whatever'

您可能会发现避免关联子查询的效率更高,如下所示...

SELECT
  *
FROM
  customer_records
INNER JOIN
  (SELECT CustomerID, MAX(ActionDate) AS ActionDate FROM customer_actions GROUP BY CustomerID) AS last_action
    ON customer_records.CustomerID = last_action.CustomerID
INNER JOIN
  customer_actions 
    ON  customer_actions.CustomerID = last_action.CustomerID
    AND customer_actions.ActionDate = last_action.ActionDate
WHERE
  customer_actions.ActionType = 'Whatever'

我不确定我是否理解要求,但是在我看来,JOIN就足够了。

SELECT  cr.CustomerID, cr.CustomerName, ...
FROM    customer_records cr
        INNER JOIN customer_actions ca ON ca.CustomerID = cr.CustomerID
WHERE   `ActionType` = 'whatever'
ORDER BY
        ca.EntryID

请注意,20.000条记录不应引起性能问题

请注意,我已经调整了Lieven的答案(我写了一篇单独的文章,因为这太久了,无法发表评论)。 该解决方案本身值得大家称赞,我只是想向您展示一些提高性能的关键点。

如果需要考虑速度,则以下内容应为您提供一些改进建议:

select top 100 -- Change as required
        cr.CustomerID ,
        cr.CustomerName,
        cr.MoreDetail1,
        cr.Etc
from    customer_records cr
        inner join customer_actions ca 
            on ca.CustomerID = cr.CustomerID
where   ca.ActionType = 'x'
order by cr.CustomerID

一些注意事项:

  • 在某些情况下,我发现左外连接要比内连接快-对于此查询,这两个都应该衡量性能
  • 尽可能避免返回*
  • 您不必在初始选择中引用“ cr.x”,但是当您开始处理可以包含多个联接的大型查询时,这是一个好习惯(一旦开始,这很有意义)做这个
  • 使用联接时, 始终联接主键

也许我缺少了一些东西,但是简单的join和where子句怎么了?

Select ActionType, ActionTime, Note
FROM Customer_Records CR
INNER JOIN customer_Actions CA 
  ON CR.CustomerID = CA.CustomerID
Where ActionType = 'added case info'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM