查询效率(多选)
我有两个表 - 一个叫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
有近2万条记录)。任何人都可以提供关于如何将查询的这个怪物排序或调整我的表以提供更快结果的任何提示?我正在使用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的记录不应该造成性能问题
请注意,我已经适应利芬的答案(我做了一个单独的职位,因为这是一个评论太长)。解决方案本身的任何功劳都归功于他,我只是试图向您展示一些提升性能的关键点。
如果速度是一个问题,然后下面应该给你提高它的一些建议:
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
的几个注意事项:
- 在某些情况下,我发现左外连接要快,然后内部连接 - 对于这个查询,两者都值得衡量性能
- 避免返回*尽可能避免返回*
- 您不必引用'c河x',但是当你开始处理可能有多个连接的大型查询时,这是一个很好的习惯(一旦你开始这样做,这会很有意义的)
- 当总是使用连接加入主键上
也许我错过了一些东西,但是简单的连接和where子句有什么问题?
Select ActionType, ActionTime, Note
FROM Customer_Records CR
INNER JOIN customer_Actions CA
ON CR.CustomerID = CA.CustomerID
Where ActionType = 'added case info'
这是否意味着如果客户的最后一个动作(由ActionDate)是*不是*'无论'那么该客户不应该被列出?对于列出的客户,您是否只想要客户,或者他们最后的行动,还是他们所有的行为? – MatBailie 2011-12-23 00:31:13
@Dems如果客户的最新'ActionType'不是'任何',那么他们不应该被显示。对于那些拥有最新'ActionType'的'无论'我都需要'customer_records'的信息 - 但这并不需要在一个查询中全部覆盖。 – Jonathon 2011-12-23 00:41:28