【问题标题】:Optimization of MySQL query have millions of records优化 MySQL 查询拥有数百万条记录
【发布时间】:2016-05-26 23:26:37
【问题描述】:

目标:需要查询以计算当前公司之外的所有“不同”潜在客户,这些潜在客户在当前公司中不存在。查询需要考虑多个表(lead_details、domains、company)之间的数百万条记录

EXAMPLE: 
  company 1 -> domain 1 -> lead 1 lead_details records exists.
  company 2 -> domain 2 -> lead 1 lead_details records exists.  
  company 2 -> domain 2 -> lead 2 lead_details records exists. 
  company 3 -> domain 3 -> lead 2 lead_details records exists. 
  company 3 -> domain 3 -> lead 3 lead_details records exists.

结果:如果我在公司 1 上运行上述数据的查询,结果应该是计数 (2),因为线索 2 和线索 3 是唯一的,并且在公司 1 中不存在

domain_id domain_name company_id company_name lead_id lead_count
    "2"         "D2"        "2"       "C2"        "2"      "2"
    "3"         "D3"        "3"       "C3"        "3"      "1"

这是我的查询,如果有人有更好的建议,请告诉我。

SELECT al.*
FROM (
    SELECT 
    d.id AS domain_id, 
    d.name AS domain_name, 
    c.id AS company_id, 
    c.name AS company_name, 
    ld.lead_id, 
    count(ld.lead_id) as lead_count 
    FROM domains d 
    INNER JOIN company c
    ON (c.id = d.company_id AND c.id != 1)
    INNER JOIN lead_details ld 
    ON (ld.domain_id = d.id)
    GROUP BY ld.lead_id
) al 
LEFT JOIN (
    SELECT ld.lead_id FROM domains d 
    INNER JOIN company c
    ON (c.id = d.company_id AND c.id = 1)
    INNER JOIN lead_details ld 
    ON (ld.domain_id = d.id)
) ccl
ON al.lead_id = ccl.lead_id 
WHERE ccl.lead_id IS NULL;

我有近百万行,所以需要找出更好的解决方案..

【问题讨论】:

  • 请将SHOW CREATE TABLE domains 的输出添加到您的问题中,companylead_details 表也是如此。这将使我们能够查看现有索引以及验证数据类型。

标签: mysql query-optimization


【解决方案1】:

A计划

模式

FROM ( SELECT ... )
JOIN ( SELECT ... ) ON ...

效率低下,尤其是在旧版本的 MySQL 中。这是因为两个子查询都没有任何索引,因此(在旧版本中)需要对其中一个子查询进行重复的全表扫描。

更好的方法是尝试重新表述为

FROM t1 ...
JOIN t2 ... ON ...
JOIN t3 ... ON ...
LEFT JOIN t4 ... ON ...
LEFT JOIN t5 ... ON ...

B计划

这更接近你所拥有的......

CREATE TEMPORARY TABLE ccl
        ( INDEX(lead_id) )
    SELECT ... -- the stuff that is after LEFT JOIN

然后将该子查询替换为 ccl。这提供了原始查询中缺少的索引。

C 计划

汇总表。 (这对于您的查询可能实用也可能不实用,因为您正在寻找 distinct 并且 不存在。)每个月(或一周或其他任何时间)计算最后一个小计月并将其存储到另一个表中。然后对这个其他表的查询会快得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-16
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多