我需要改进此SQL UPDATE查询。查询必须只更新第一行,但我怀疑它在所有行上运行并为所有行运行子查询时使用了很多功能,因为在使用大数据库时它非常慢。有什么建议吗?
UPDATE leads l
SET status='processing', processor='$processor'
WHERE pool IN ($pools) AND status='active'
ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC
LIMIT 1
更新
缓慢确实是由子选择引起的。典型的潜在客户表中可能有2000-3000个匹配项。最简单的方法是在lead-table中构建一个手动计数调用的列,这样我就不需要subselect,但它是一个需要进行这些更改的运行站点,因此如果需要进行更改,则会导致订单陷入困境。我现在添加了专栏。
但我认为这是避免大型子选择的唯一方法。
答案 0 :(得分:0)
对我来说 - 慢慢来自次选。对于每个pool
,您查询所有calls
以计算它们的数量。首先要确保calls.lead
被编入索引。您可以将该计数器保留在pool
中,并设置触发器以保持真实性。其他选择是将该信息保留在索引中,但我无法告诉如何在MySQL上使用它,特别是在未知版本上
答案 1 :(得分:0)
在列pool
和status
的lead-table上创建多列索引将是加快更新速度的最简单方法。但是你的主要表中确实有多少行?你的where子句适合多少行?
多列索引
ALTER TABLE your_schema.leads
ADD INDEX faster_update(pool,status) ;
另外,为什么您只更新符合条件的有限数量的行?您可能希望提供有关您案例的更多信息,以获得最有帮助的答案。并使用“大”的子选项。在更新之前对表进行排序听起来像是关于执行时间的坏主意因为订单可能比更新本身花费更多时间。
如果您不知道是否使用了索引,请使用以下代码分析您的查询:
EXPLAIN EXTENDED SELECT * FROM your_schema.leads
WHERE pool IN ($pools) AND status='active'
ORDER BY (SELECT count(*) FROM calls c WHERE c.lead = l.id), id ASC
或者只是在这里发布结果