运行此MySQL查询的最快方法是按计数的增加&减少?

时间:2011-04-24 19:09:15

标签: mysql sql query-optimization

我有一张桌子记录了商店里350多种产品的每一笔销售情况;列包括产品名称和日期。

我正在开发一个页面,其中列出了基于销售增长百分比的最快移动产品,但考虑到有350多种产品和60000多条记录,我的查询非常缓慢。

  SELECT product_name, date 
    FROM data 
ORDER BY ((SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date2') - 
          (SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date1')) / 
          (SELECT COUNT(ID) 
             FROM data 
            WHERE date='$date1') DESC

我的MySQL知识非常有限,所以社区的任何帮助都将受到赞赏。

数据样本:

| id | product_name    | date       |
| 1  | pen             | 2011-04-22 |
| 2  | pencil          | 2011-04-22 |
| 3  | pen             | 2011-04-23 |
| 4  | pen             | 2011-04-23 |
| 5  | pencil          | 2011-04-23 |
| 6  | pen             | 2011-04-23 |
| 7  | pencil          | 2011-04-23 |

预期产出:

1  Pen     200%  (3-1)/1
2  Pencil  100%  (2-1)/1

2 个答案:

答案 0 :(得分:1)

取消双重选择
如果您创建一个存储函数,如下所示:

DELIMITER $$

CREATE FUNCTION SalesIncrease(OldSales integer, NewSales integer)
  RETURNS float
BEGIN
  DECLARE Result float;
  IF OldSales = 0 THEN SET result = 1; /*100%*/
  ELSE BEGIN
    IF NewSales = 0 THEN SET result = -1; /*-100%*/ 
    ELSE SET Result = (NewSales - OldSales) / OldSales;
    END IF;
  END; END IF;

  RETURN result;
END $$

DELIMITER ;

现在将查询更改为

//don't forget to escape $date1 and $date2 to protect against SQL-injection
$date1 = mysql_real_escape_string($date1);
$date2 = mysql_real_escape_string($date2);

$sql_query = "SELECT oldsales.product_name, oldsales.date, 
  SalesIncrease( COUNT(oldsales.ID), COUNT(newsales.ID)) as Increase 
FROM data AS oldsales
LEFT join data AS newsales ON (oldsales.id = newsales.id)
WHERE oldsales.date = '$date1' AND newsales.date = '$date2'
ORDER BY Increase ";

答案 1 :(得分:0)

SELECT COALESCE(d2.product_name, d1.product_name) AS product_name, 
       COALESCE(100*(COALESCE(d2.n, 0)/d1.n -1), 'Infinity') AS pct_increase
FROM (SELECT product_name, COUNT(id) AS n FROM data WHERE date=$date1
     GROUP BY product_name) as d1 
FULL OUTER JOIN 
     (SELECT product_name, COUNT(id) AS n FROM data WHERE date=$date2
     GROUP BY product_name) as d2
ON d1.product_name=d2.product_name
ORDER BY 2 DESC; 
/* BY 2 == second column, nonstandard SQL but works. Can also copy column expression */

确保您在product_name和日期索引上有索引。

COALESCE用于处理其中一个日期没有销售的边缘情况,就像使用OUTER JOIN一样。