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

Posted

技术标签:

【中文标题】索引了 1500 万客户,但查询仍然需要将近 5 分钟才能返回结果【英文标题】:Indexed 15 million customers but query still takes almost 5mins to return results 【发布时间】:2018-06-25 21:05:22 【问题描述】:

我在 3 列中有 1500 万个客户数据,并且每列都有索引:

    客户 Index ix_disabled_customer_id on zen_customers(customers_id, disabled); customer_attribute Index ix_attribute_id_and_name onzen_customers(attribute_id, attribute_name); 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

如果我能得到优化此过滤的想法,我将不胜感激。谢谢

【问题讨论】:

请附上解释的结果。 请到以下链接查看解释扩展计划。 i.stack.imgur.com/i9SAZ.png我也添加了这个问题。 请为 3 张桌子提供SHOW CREATE TABLE 【参考方案1】:

首先,建议使用 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)

索引中列的顺序很重要。

【讨论】:

【参考方案2】:

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

您的架构通过规范化值而不是将它们放入属性表中,从而使情况变得非常糟糕。

关注标签 [entity-attribute-value] 以获得进一步的启发。

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

【讨论】:

以上是关于索引了 1500 万客户,但查询仍然需要将近 5 分钟才能返回结果的主要内容,如果未能解决你的问题,请参考以下文章

查询花了将近两秒但只匹配两行 - 为什么索引没有帮助?

这是一个数独求解程序。我遇到了递归错误。我导入了 sys 模块并将递归限制设置为 1500,但仍然显示错误

为啥使用索引但sql仍然很慢

为啥 oracle 表索引但仍然进行全表扫描?

包含 5000 万数据的表和添加索引需要太多时间

sql处理千万数据查询缓慢问题