索引了1500万客户,但查询仍然需要近5分钟才能返回结果

时间:2018-06-25 21:05:22

标签: mysql query-optimization entity-attribute-value

我在3列中拥有1500万个客户数据,并在每个列中建立了索引:

  1. 客户
    • Index ix_disabled_customer_id on zen_customers(customers_id, disabled);
  2. customer_attribute
    • Index ix_attribute_id_and_name on zen_customers (attribute_id, attribute_name);
  3. customer_attribute_value。
    • Index ix_attribute_id_and_customer_id on `zen_customers`(customers_id, attribute_id);

我正在尝试使用Gender筛选客户,并且返回结果花费的时间太长。

以下是查询

SELECT tcav.customers_id AS customers_id 
FROM customer_attribute_value tcav
JOIN customer_attribute tca
JOIN customers zc
WHERE tcav.attribute_id = tca.attribute_id
    AND tca.attribute_name = "Gender"
    AND tcav.attribute_value = "M"
    AND zc.customers_id = tcav.customers_id
    AND  zc.disabled = 0;

Image Added for Explain Extended plan

如果能提出优化此过滤条件的想法,我将不胜感激。谢谢

2 个答案:

答案 0 :(得分:0)

首先,建议使用ON子句代替WHERE子句连接表。它不太可能对性能产生任何影响,但确实有助于提高查看哪些列与哪些表相关的能力。

SELECT tcav.customers_id AS customers_id 
FROM tulip_customer_attribute_value tcav
JOIN tulip_customer_attribute tca
ON tcav.attribute_id = tca.attribute_id
JOIN zen_customers zc
ON zc.customers_id = tcav.customers_id
WHERE tca.attribute_name = "Gender"
AND tcav.attribute_value = "M"
AND zc.disabled = 0

添加以下索引:

tulip_customer_attribute (attribute_name,attribute_id)

tulip_customer_attribute_value (attribute_id,attribute_value,customers_id)

索引中列的顺序很重要。

答案 1 :(得分:-1)

EAV模式有很多问题。在这种情况下,您可能会花费大量空间和时间查找“性别”,而这可能更有效地放在主表中。

您的模式通过规范化值,而不是将其放在属性表中,使情况变得更加糟糕。

按照标签[entity-attribute-value]进行进一步的启发。

在认真修改架构之前,随着数据的增长,性能将从糟糕变为糟糕。