我在 mysql (innodb) 上有一个大表,其中包含产品 Assets (1300 万行)。这是我的数据库的一些模式:
product <-many2one-- file_item --one2many--> family --many2one--> download_type
*file_item* 表是具有数百万行的大表。我尝试使用以下 sql 查询按下载类型计算产品:
select t.name as type,
count(p.product_id) as n
from file_item p
inner join family f on f.id = p.family_id
inner join type t on f.id_type = t.id
group by t.id order by t.name;
*file_item* 表有 3 个索引:
- product_family_idx(product_id,family_id)
- family_idx (family_id)
- product_idx (product_id) 解释输出:
+----+-------------+-------+--------+-----------------------------------+---------+---------+-------------------+----------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+-----------------------------------+---------+---------+-------------------+----------+---------------------------------+ | 1 | SIMPLE | p | ALL | FAMILY_IDX,PRODUCT_FAMILY_IDX | NULL | NULL | NULL | 13862870 | Using temporary; Using filesort | | 1 | SIMPLE | f | eq_ref | PRIMARY,TYPE_ID | PRIMARY | 4 | MEDIA.p.FAMILY_IDX| 1 | | | 1 | SIMPLE | t | eq_ref | PRIMARY | PRIMARY | 4 | MEDIA.f.TYPE_ID | 1 | | +----+-------------+-------+--------+-----------------------------------+---------+---------+-------------------+----------+---------------------------------+
查询需要1个多小时才能返回结果。 请问我该如何优化查询?!
最佳答案
这是您的原始查询:
select t.name as type,
count(p.product_id) as n
from file_item p
inner join family f on f.id = p.family_id
inner join type t on f.id_type = t.id
group by t.id order by t.name;
您需要进行两项主要更改:
主要变化#1:重构查询
SELECT A.ProductCount,B.name type
FROM
(
SELECT id_type id,COUNT(1) ProductCount
FROM
(
SELECT p.id_type
FROM (SELECT family_id,id_type FROM file_item) p
INNER JOIN (SELECT id FROM family) f on f.id = p.family_id
) AA
GROUP BY id_type
) A
INNER JOIN type B USING (id)
ORDER BY B.name;
主要变化#2:创建支持重构查询的索引
ALTER TABLE file_item ADD INDEX family_type_idx (family_id,id_type);
试一试!!!
关于mysql - 如何优化大表上的计数 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7178849/