我有一个复合键表CUSTOMER_PRODUCT_XREF
__________________________________________________________________
|CUSTOMER_ID (PK NN VARCHAR(191)) | PRODUCT_ID(PK NN VARCHAR(191))|
-------------------------------------------------------------------
在我的批处理程序中,我需要选择500个更新的客户,并获得由逗号分隔的逗号所购买的PRODUCT_ID,并更新我们的SOLR索引。在我的查询中,我选择了500个客户,然后左边加入CUSTOMER_PRODUCT_XREF
SELECT
customer.*, group_concat(xref.PRODUCT_ID separator ', ')
FROM
CUSTOMER customer
LEFT JOIN CUSTOMER_PRODUCT_XREF xref ON customer.CUSTOMER_ID=xref.CUSTOMER_ID
group by customer.CUSTOMER_ID
LIMIT 500;
编辑:EXPLAIN QUERY
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE customer ALL PRIMARY NULL NULL NULL 74236 Using where; Using temporary; Using filesort
1 SIMPLE xref index NULL PRIMARY 1532 NULL 121627 Using where; Using index; Using join buffer (Block Nested Loop)
运行上述查询20分钟后,我丢失了连接异常。
我尝试使用以下(子查询)并获得结果需要1.7秒但仍然很慢。
SELECT
customer.*, (SELECT group_concat(PRODUCT_ID separator ', ')
FROM CUSTOMER_PRODUCT_XREF xref
WHERE customer.CUSTOMER_ID=xref.CUSTOMER_ID
GROUP BY customer.CUSTOMER_ID)
FROM
CUSTOMER customer
LIMIT 500;
编辑:EXPLAIN QUERY生成
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY customer ALL NULL NULL NULL NULL 74236 NULL
2 DEPENDENT SUBQUERY xref index NULL PRIMARY 1532 NULL 121627 Using where; Using index; Using temporary; Using filesort
问题
CUSTOMER_PRODUCT_XREF已将两列设置为PRIMARY_KEY和NOT_NULL,但为什么我的查询仍然很慢?我认为在列上使用主键足以为它构建索引。我需要进一步索引吗?
数据库信息:
答案 0 :(得分:0)
您的原始版本的查询首先执行join
,然后对所有结果数据进行排序 - 考虑到字段的大小,这可能非常大。
您可以先选择500个客户然后再进行加入来“修复”该版本:
SELECT c.*, group_concat(xref.PRODUCT_ID separator ', ')
FROM (select c.*
from CUSTOMER customer c
order by c.customer_id
limit 500
) c LEFT JOIN
CUSTOMER_PRODUCT_XREF xref
ON c.CUSTOMER_ID=xref.CUSTOMER_ID
group by c.CUSTOMER_ID ;
可能会或可能不会产生重大影响的替代方案是在子查询中按客户进行聚合并加入,如:
SELECT c.*, xref.products
FROM (select c.*
from CUSTOMER customer c
order by c.customer_id
limit 500
) c LEFT JOIN
(select customer_id, group_concat(xref.PRODUCT_ID separator ', ') as products
from CUSTOMER_PRODUCT_XREF xref
) xref
ON c.CUSTOMER_ID=xref.CUSTOMER_ID;
您发现的是MySQL优化器无法识别这种情况(限制对性能有很大影响)。在这种情况下,其他一些数据库引擎可以更好地进行优化。
答案 1 :(得分:0)
当我在CUSTOMER_PRODUCT_XREF表中的CUSTOMER_ID上创建索引时,我的问题中查询的速度很快就会出现。
所以我现在有两个索引 PRODUCT_ID和CUSTOMER_ID上的PRIMARY_KEY_INDEX CUSTOMER_ID上的CUSTOMER_ID_INDEX