我在3列中拥有1500万个客户数据,并在每个列中建立了索引:
Index ix_disabled_customer_id on zen_customers(customers_id, disabled);
Index ix_attribute_id_and_name on
zen_customers (attribute_id, attribute_name);
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
如果能提出优化此过滤条件的想法,我将不胜感激。谢谢
答案 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]进行进一步的启发。
在认真修改架构之前,随着数据的增长,性能将从糟糕变为糟糕。