使用if语句重用count

时间:2016-04-01 08:01:29

标签: mysql

我想优化以下查询以避免多次计数运行。

SELECT product.Id,
    IF((SELECT COUNT(*) 
        FROM productorders 
        WHERE productorders.ProductId = product.Id) > 0,
       (SELECT COUNT(*) FROM productorders WHERE productorders.ProductId = product.Id),
       9999999999
    )
FROM product

有人可以提出相同的解决方案

我在幻数9999999999中使用更复杂的逻辑,为简单起见,我在这里避免使用

此查询也是一个更大的查询的一小部分......我为了简单起见而避免使用

解释结果如下

+选项id select_type表类型possible_keys键key_len ref rows Extra

1 主 产品 指数 空值 类别编号 8 空值 25 使用索引

3

相关的子信息 productorders REF 主 主 8 tabletest.product.Id 1 使用索引 2

相关的子信息 productorders REF 主 主 8 tabletest.product.Id 1 使用索引

4 个答案:

答案 0 :(得分:0)

我认为在查询之前将计数查询结果作为MySQL变量启动,在IF语句中使用它或将计数结果分配给查询中的变量内联并稍后重用变量可能是一个答案。可以在这里找到一些灵感:How to store Query Result in variable using mysql

答案 1 :(得分:0)

编辑,这可以很好地工作,并在没有行时返回0:

SELECT product.Id,
       COUNT(productorders.ProductId)
FROM product
LEFT JOIN productorders ON productorders.ProductId = product.Id
GROUP BY productorders.Id

如果你想要它返回99999999(我强烈反对你做)而不是零,你只需从sergey添加if语句并将其更改为:

SELECT product.Id,
       IF(COUNT(productorders.ProductId)>0, COUNT(productorders.ProductId), 99999999)
FROM product
LEFT JOIN productorders ON productorders.ProductId = product.Id
GROUP BY productorders.Id

在这种情况下,在你的选择中有2个COUNT函数不应该使查询更慢。

以下是我在我自己的数据库中进行的类似查询的解释结果(可能是错误的例子,因为行数不多,我建议您在自己的数据库中尝试自己):

无IF解释:

EXPLAIN SELECT tbl_stam_land.Land_ID,
     COUNT(tbl_naw_adres.Land_ID)
FROM tbl_stam_land
LEFT JOIN tbl_naw_adres ON tbl_naw_adres.Land_ID = tbl_stam_land.Land_ID
GROUP BY tbl_naw_adres.Adres_ID;
/* Affected rows: 0  Gevonden rijen: 2  Waarschuwingen: 0  Duur van 1 query: 0,015 sec. */

用IF解释:

EXPLAIN SELECT tbl_stam_land.Land_ID,
     IF(COUNT(tbl_naw_adres.Land_ID) > 0, COUNT(tbl_naw_adres.Land_ID), 99999999)
FROM tbl_stam_land
LEFT JOIN tbl_naw_adres ON tbl_naw_adres.Land_ID = tbl_stam_land.Land_ID
GROUP BY tbl_naw_adres.Adres_ID;
/* Affected rows: 0  Gevonden rijen: 2  Waarschuwingen: 0  Duur van 1 query: 0,015 sec. */

0,015秒纯粹来自传输延迟,它在0,015和0,032之间变化。

编辑:我的不好,在我正在使用它的程序中会自动添加查询运行的时间。查看这篇文章,了解如何衡量查询执行的时间:

mysql execution time

答案 2 :(得分:0)

最好使用聚合进行用户查询,例如

SELECT product.Id, count(productorders.ProductId) 
FROM product left outer join productorders 
on productorders.ProductId=product.Id 
group by product.Id

使用9999999999的逻辑最好在客户端上实现,使用幻数是很危险的。明确地实现它 - 如果订单数量== 0,做一些事情,否则 - 使用收到的数字。

如果您仍想使用幻数,请尝试以下查询:

SELECT product.Id, 
IF(count(productorders.ProductId)>0, 
count(productorders.ProductId), 9999999999)
FROM product 
left outer join productorders on productorders.ProductId=product.Id
group by product.Id

答案 3 :(得分:0)

使用MySQL 用户定义变量的优化解决方案

SET @counter := 0;
SELECT product.Id,
       @counter := (SELECT COUNT(*) FROM productorders WHERE productorders.ProductId = product.Id) as cond,
       IF(@counter > 0, @counter, 9999999999) as counter
FROM product

我发现您一直希望只获取product.Idcounter字段 - 从子查询中选择:

SELECT product_id, counter(
       SELECT product.Id as product_id,
           @counter := (SELECT COUNT(*) FROM productorders WHERE productorders.ProductId = product.Id) as cond,
           IF(@counter > 0, @counter, 9999999999) as counter
       FROM product) as counter