Mysql 在同一个表上使用联接进行缓慢聚合查询
我有一个查询,显示客户及其所有订单的总美元价值。执行查询大约需要100秒 我正在查询ExpressionEngine CMS数据库。ExpressionEngine对所有内容使用一个表Mysql 在同一个表上使用联接进行缓慢聚合查询,mysql,sql,expressionengine,Mysql,Sql,Expressionengine,我有一个查询,显示客户及其所有订单的总美元价值。执行查询大约需要100秒 我正在查询ExpressionEngine CMS数据库。ExpressionEngine对所有内容使用一个表exp\u channel\u data。因此,我必须在该表中加入客户和订单数据。我在该表中有大约14000个客户、30000个订单和160000个总记录 我可以更改此查询以加快速度吗 SELECT link.author_id AS customer_id, customers.
exp\u channel\u data
。因此,我必须在该表中加入客户和订单数据。我在该表中有大约14000个客户、30000个订单和160000个总记录
我可以更改此查询以加快速度吗
SELECT link.author_id AS customer_id,
customers.field_id_122 AS company,
Sum(orders.field_id_22) AS total_orders
FROM exp_channel_data customers
JOIN exp_channel_titles link
ON link.author_id = customers.field_id_117
AND customers.channel_id = 7
JOIN exp_channel_data orders
ON orders.entry_id = link.entry_id
AND orders.channel_id = 3
GROUP BY customer_id
谢谢,如果我需要包括其他信息,请告诉我
更新解决方案
我道歉。我注意到exp\u channel\u data
表客户的entry\u id
对应于exp\u channel\u titles
表的author\u id
。因此,我不必在连接中使用字段\u id\u 117
<代码>字段\u id\u 117重复条目\u id
,但在文本字段中。加入到文本字段中会减慢速度。查询现在3秒
然而,@DRapp发布的内部连接解决方案是1.5秒。以下是他的sql,只需稍加编辑:
SELECT
PQ.author_id CustomerID,
c.field_id_122 CompanyName,
PQ.totalOrders
FROM
( SELECT
t.author_id
SUM( o.field_id_22 ) as totalOrders
FROM
exp_channel_data o
JOIN
exp_channel_titles t ON t.author_id = o.entry_id AND o.channel_id = 3
GROUP BY
t.author_id ) PQ
JOIN
exp_channel_data c ON PQ.author_id = c.entry_id AND c.channel_id = 7
ORDER BY CustomerID
试试这样的。可能在联接中有错误。还要检查数据库中列上的联接是否正确。如果列上的连接不正确,则交叉连接可能需要时间来获取大数据
select
link.author_id as customer_id,
customers.field_id_122 as company,
sum(orders.field_id_22) as total_or_orders
from exp_channel_data customers
join exp_channel_titles link on (link.author_id = customers.field_id_117 and
link.author_id = customer.channel_id = 7)
join exp_channel_data orders on (orders.entry_id = link.entry_id and orders.entry_id = orders.channel_id = 3)
group by customer_id
你能发布
解释查询的结果吗
我猜您的表在这个操作中没有很好的索引。您连接的所有列可能都应该编制索引。首先,我想看看索引exp\u channel\u data.field\u id\u 117
如果这是同一个表,那么所有别名实例的所有列都是相同的。
如果可能的话,我会确保在(通道id、入口id、字段id)上建立索引。(author_id)上的另一个索引,用于预查询订单总数
然后,首先从一个内部查询开始,它只做每个客户的订单金额总和。。因为连接是作为客户id的“author\u id”,所以只需首先查询/求和即可。如果不完全理解(我会考虑的)结构的糟糕设计,不知道“Channel_ID”真正表示的是什么,您就不想因为混合中的这些其他东西而重复求和值
select
o.author_id,
sum( o.field_id_22 ) as totalOrders
FROM
exp_channel_data customers o
where
o.channel_id = 3
group by
o.author_id
如果在每个客户(通过author_id列)上这是正确的,那么可以按如下方式包装
select
PQ.author_id CustomerID,
c.field_id_122 CompanyName,
PQ.totalOrders
from
( select
o.author_id,
sum( o.field_id_22 ) as totalOrders
FROM
exp_channel_data customers o
where
o.channel_id = 3
group by
o.author_id ) PQ
JOIN exp_channel_data c
on PQ.author_id = c.field_id_117
AND c.channel_id = 7
谢谢我尝试在您的查询中使用联接条件,但不幸的是没有返回结果。可能是您的联接或指定的列名错误。尝试不使用别名。还应尽量少使用表进行联接。您可以发布解释查询的结果吗?我猜您的表在这个操作中没有很好的索引。您连接的所有列可能都应该编制索引。首先,我想看一下索引exp\u channel\u data.field\u id\u 117。您是对的,exp\u channel\u data.field\u id\u 117
没有索引。它实际上是一个文本字段,除了该表中的关键字段之外,所有字段都是文本字段。所以我把它改成了varchar,这样我就可以添加一个索引,这很有帮助。事实证明,我不需要字段\u id\u 117
,尽管在我的更新中如此。谢谢非常感谢。后来我意识到我不必在连接中使用字段id\u 117
,这是主要问题,但您的查询速度仍然是原来的两倍。您是对的,exp\u channel\u data。字段id\u 117
是个魔鬼。它是一个文本字段,所以它甚至不能被索引。幸运的是,我后来发现我不必使用它。