mySQL Count子查询超级慢,没有那么多记录

时间:2017-03-31 12:54:23

标签: mysql count subquery

我有一个巨大的UNIONed查询,它由13个查询组成,如下所示,具有不同的category_id-s。它们在两台服务器上运行:

  • 普通ssd vps上的第一个产品中有18000多条记录,用户中有19000多条记录
  • 第二个是基于云的(digitalocean,linode)产品有3000多条记录,用户有13000多条记录。 (重要的东西,1个用户有2200多种产品)

两个表(我相信)都已正确索引,设置几乎是默认的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来解决这个问题。

0 个答案:

没有答案