我有一个巨大的UNIONed查询,它由13个查询组成,如下所示,具有不同的category_id-s。它们在两台服务器上运行:
两个表(我相信)都已正确索引,设置几乎是默认的mySQL 5.6设置
整个查询:
SELECT SQL_CALC_FOUND_ROWS mylist.* FROM
(
MAIN SELECT
UNION SUBCATEGORIES SELECT ... WHERE (COUNT)
UNION SUBCATEGORIES SELECT ... WHERE (COUNT)
x13
) mylist
ORDER ...
其中一个子类别选择如下所示:
SELECT products.*
FROM
products
LEFT JOIN
users ON (products.user_id = users.id)
WHERE
products.lang = 'en'
AND
products.category_id IN (61, 63, 154, 155, 64, 65, 156, 66, 67, 68, 157, 195, 69, 70, 158, 170, 171, 203, 204, 205)
AND
products.deleted = 0
AND
products.public = 1
AND
users.banned = 0
AND
users.deleted = 0
AND
users.active = 1
AND
users.type = 'company'
AND
(
SELECT COUNT(*)
FROM products AS products2
WHERE
products2.user_id = products.user_id
AND
products2.lang = products.lang
AND
products2.category_id IN (61, 63, 154, 155, 64, 65, 156, 66, 67, 68, 157, 195, 69, 70, 158, 170, 171, 203, 204, 205)
AND
products2.deleted = 0
AND
products2.public = 1
AND
products2.created >= products.created
) <= 25
ORDER BY
products.created DESC
整个QUERY在第一台服务器上需要1-2秒,在第二台服务器上需要14-18秒。
很明显,这是因为一个用户拥有2200多种产品,并且由于子查询计数而产生的问题显然是乘以行乘以倍数,但我并不真正理解它,因为这个用户有很多类别的产品,但没有其他查询部分那么慢。也是最有趣的部分,用户是&#39; person&#39;类型,所以他的产品甚至不包括在这个查询部分...... 此部分最多需要10秒钟才能运行。
此外,我还没有真正看到,我如何优化和重构此查询,以避免以后在其他用户访问这么多产品时出现慢查询。
编辑1:临时表不是一个选项,因为在mySQL临时表中不能在多个查询中引用。
编辑2:Explain result
编辑3:我不能透露任何特定数据。
但是我没有编写查询,以前的开发人员做了,重写它有点困难,特别是因为很多列表使用它 - 或者它的某些部分 - ,这是主要的一个查询。
如果您在一个子类别中,那么只有那些subcat过滤查询联合的部分才会被生成&#39;这些部分位于当前类别中,如果您理解我的意思。
由不同类别组成的部分&#39;子类别过滤器,并且该脚本仅产生那些用户在具体类别或其子类别中不超过25个的产品,如您在附加脚本中所见。
我没有真正看到一种方便快捷的重写方法,而无需完全重写核心概念。我尝试使用临时表,但在mySQL中,你不能再引用一次临时表。使用视图与主视图一样慢,因为每次引用它时,它都必须刷新视图,而且我不能创建总和表,因为我们需要在每个类别的子类别中加总。
对于使用连接进行重构存在同样的问题,因为这样脚本必须加入每个产品的子类别中的总和计数,它会像这个一样慢,或者可能更慢而且我可以更慢。我也不确定,是否可以通过JOIN来解决这个问题。