MYSQL Stuck生成临时表(海量查询)

时间:2017-04-11 07:58:12

标签: mysql sql

我有4张桌子(1对多): 不要说那个“电子邮件”关系。这是我的开发人员老板多年前建立它的方式。

EMPLOYEES (+-50 results)
------------------------------------------------
id    name    
1     EmpName 1
2     EmpName 2  

CUSTOMERS (+50k results)
------------------------------------------------
id    name    email            employee_assigned
1     John    john@doe.com     12
2     Donald  donald@duck.com  6

INTERESTS_CATEGORIES (+650k results)
------------------------------------------------
id    customer_email    category_id
1     john@doe.com      97
2     john@doe.com      13
3     donald@duck.com   56
4     donald@duck.com   126
5     donald@duck.com   45

INTERESTS_PRODUCTS (+650k results)
------------------------------------------------
id    customer_email    product_id
1     john@doe.com      78
2     john@doe.com      23
3     donald@duck.com   19
4     donald@duck.com   56
5     donald@duck.com   45

所以我需要按照指定的员工和他们的兴趣过滤客户。 这是查询:

SELECT
    *
FROM          
(
    SELECT 
        customers.id                        AS 'id',
        customers.name                      AS 'first_name',
        customers.email,
        employees.id                        AS 'employee_id'
    FROM 
        customers, 
        employees
    WHERE 
        employees.id = 2
        AND 
        customers.employee_assigned = employees.id
) AS myCustomers

LEFT JOIN interests_categories 
    ON interests_categories.customer_email = myCustomers.email
LEFT JOIN interests_products 
    ON interests_categories.customer_email = myCustomers.email
WHERE       
( 
    interests_categories.category_id = 20
    OR 
    interests_categories.category_id = 21
)

GROUP BY myCustomers.email

所以,问题是:

  • 如果员工的分配客户数量较少(如3),则查询 是成功的。

  • 如果员工中等数量的已分配客户(超过100个)查询卡住了。

我执行SHOW PROCESSLIST并且它被称为“生成临时表”。

有人有想法吗? :( 谢谢。

2 个答案:

答案 0 :(得分:0)

检查表上的索引并尝试:

SELECT 
    c.id AS 'id',
    c.name AS 'first_name',
    c.email,
    e.id AS 'employee_id'
    ic.*,
    ip.*
FROM customers c
JOIN employees e
ON c.employee_assigned = e.id
LEFT JOIN interests_categories ic
    ON ic.customer_email = c.email
LEFT JOIN interests_products ip
    ON ic.customer_email = c.email
WHERE      
( 
    ic.category_id IN (20,21)
    AND e.id = 2
)
GROUP BY myCustomers.email

答案 1 :(得分:0)

顺便提一下,一个不那么愚蠢的设计可能如下所示。如果是我,我会从这开始,并相应地提供适当代表性的CREATE和INSERT语句。此外,我很想知道category_id来自哪里 - 因为这可能是进一步优化的领域。

EMPLOYEES 
------------------------------------------------
employee_id name    
          6 EmpName 1
         12 EmpName 2  

CUSTOMERS 
------------------------------------------------
customer_id name    email            employee_assigned
          1 John    john@doe.com                    12
          2 Donald  donald@duck.com                  6

INTERESTS_CATEGORIES 
------------------------------------------------
customer_id category_id
          1          97
          1          13
          2          56
          2         126
          2          45

INTERESTS_PRODUCTS 
------------------------------------------------
customer_id product_id
          1         78
          1         23
          2         19
          2         56
          2         45
相关问题