gpt4 book ai didi

mysql - 带有依赖子查询的慢 MySQL 查询(检查客户端是否是第一种情况)

转载 作者:行者123 更新时间:2023-11-30 01:02:25 24 4
gpt4 key购买 nike

我有一个 SQL 查询 (MySQL),用于收集由特定推荐公司推荐的客户生成的新案例(职位)的详细信息。重要的是,我们只需要选择那些是客户的第一个案例,否则重复的客户会注册为被一遍又一遍地推荐,而这不是我们想要得到的。在我们的系统中,我们有客户和案例表,它们通过 m:n 表连接(实际上只是 1:n),因此用于将案例与其相应的客户相关联。

仅在客户的第一个案例中返回值的要求给我带来了麻烦。为此,我在 WHERE 子句中有一个子查询,通过查找该客户端的任何其他情况来检查特定情况是否是该客户端的第一个情况。这给出了正确的输出,但使查询运行得相当慢,而且我不知道该怎么办,这就是为什么我向 StackOverflow 寻求更好的方法。如果我删除该子查询,它会立即运行。我尝试更改子查询以检查 COUNT(*) = 0 而不是 NOT EXISTS。我还对其进行了更改以检查任何较小的 case_ids,而不是检查较早的案例创建日期。我尝试过调整其他东西,在每种情况下我都得到了类似的缓慢结果(~45 秒与即时)。我不知道如何修改事情以使其不再是依赖子查询。我想到的一个替代方案是在案例表中放入一个简单的字段,表示这是否是客户的第一个案例,但这会带来其他问题,如果可能的话,这不是我想要做的。

注意:如果客户有多个案例,我不能排除他们,因为我需要第一个案例。我不能

我本来打算为您简化查询,但后来我意识到我还必须弄清楚 EXPLAIN 结果中的结果如何才能修改这些结果,所以我没有这样做。我们有一个客户和一个联系人表,联系人是客户的子级,联系人是有案例的联系人,并且保存了按值引用的值,但我们将通过客户来确定他们之前是否有案例。

尝试1:

SELECT c2.case_id AS Case_ID, [other stuff]
FROM client_contact_cases c1 LEFT JOIN cases c2 ON (c1.case_id = c2.case_id)
LEFT JOIN client_contact c3 ON (c1.client_contact_id = c3.client_contact_id)
WHERE c2.case_created_date > '2013-05-01 00:00:00' AND c2.case_created_date < '2013-10-31 23:59:59'
AND c3.refer_by = 'Referring Partner #1'
AND NOT EXISTS (
SELECT c2_a.case_id FROM client_contact_cases c1_a LEFT JOIN cases c2_a ON (c1_a.case_id = c2_a.case_id)
WHERE c1_a.client_id = c1.client_id AND c2_a.case_created_date < c2.case_created_date
)
ORDER BY Case_ID ASC

解释结果:

'1', 'PRIMARY', 'c3', 'ALL', 'PRIMARY', NULL, NULL, NULL, '29340', 'Using where; Using     temporary; Using filesort'
'1', 'PRIMARY', 'c1', 'ref', 'client_has_cases_FKIndex1,client_contact_has_cases_FKIndex2', 'client_has_cases_FKIndex1', '4', 'prod1_cases_clients.c3.client_contact_id', '1', 'Using index'
'1', 'PRIMARY', 'c2', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'prod1_cases_clients.c1.case_id', '1', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'c1_a', 'index', 'client_contact_has_cases_FKIndex2', 'client_contact_has_cases_FKIndex2', '4', NULL, '33682', 'Using where; Using index'
'2', 'DEPENDENT SUBQUERY', 'c2_a', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'prod1_cases_clients.c1_a.case_id', '1', 'Using where'

这是如果我将子查询更改为的 EXPLAIN 结果:

...SELECT c1_a.case_id FROM client_contact_cases c1_a 
WHERE c1_a.client_id = c1.client_id AND c1_a.case_id < c2.case_id

解释:

'1', 'PRIMARY', 'c3', 'ALL', 'PRIMARY', NULL, NULL, NULL, '29340', 'Using where; Using temporary; Using filesort'
'1', 'PRIMARY', 'c1', 'ref', 'client_contact_has_cases_FKIndex1,client_contact_has_cases_FKIndex2', 'client_contact_has_cases_FKIndex1', '4', 'prod1_cases_clients.c3.client_contact_id', '1', 'Using index'
'1', 'PRIMARY', 'c2', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'prod1_cases_clients.c1.case_id', '1', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'c1_a', 'ALL', 'client_contact_has_cases_FKIndex2', NULL, NULL, NULL, '33682', 'Range checked for each record (index map: 0x4)'

“每条记录的检查范围(索引映射:0x4)”是怎么回事?一切都应该有一个索引。非常感谢任何帮助!

最佳答案

啊哈,我想出了一个不依赖的子查询!相反,我正在检查子查询中客户端第一个案例列表中的 case_ids 。现在它的运行时间不到半秒。我很乐意在 WHERE 子句中添加一些内容以进一步减少它。我无法输入日期范围,因为它会阻止查询检查以前的案例,并给我提供比应有的结果稍多的结果,但我后来添加了 c3_a.refer_by = 'Referring Partner #1'。

子查询现在是:

AND c2.case_id IN (
SELECT MIN(c2_a.case_id)
FROM client_contact_cases c1_a LEFT JOIN cases c2_a ON (c1_a.case_id = c2_a.case_id)
GROUP BY c1_a.client_id
)

关于mysql - 带有依赖子查询的慢 MySQL 查询(检查客户端是否是第一种情况),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19990331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com