太多的笛卡尔产品,使查询运行速度变慢

时间:2015-02-20 11:41:18

标签: mysql query-optimization cartesian-product

考虑我有两个表DETAILS AND RATE,其中包含以下列:

DETAILS表:

CREATE TABLE DETAILS(
LONG ID PRIMARY KEY AUTO_INCREMENT,
DOUBLE PRICE1,
DOUBLE PRICE2,
DOUBLE PRICE3,
VARCHAR(25) CURRENCY,
DATE CREATED_DATE,
VARCHAT(50) COMPLETED
..................
Few more columns
);

评价表:

CREATE TABLE RATE(
LONG ID PRIMARY KEY AUTO_INCREMENT,
DOUBLE RATE,
VARCHAR(25) CURRENCY,
DATE CREATED_DATE
..................
Few more columns
);

我有一个DETAILS表的更新查询,如下所示。

UPDATE DETAILS D, RATE R 
SET D.PRICE1=D.PRICE1*R.RATE,
D.PRICE2=D.PRICE2*R.RATE,
D.PRICE3=D.PRICE3*R.RATE
WHERE
D.CURRENCY=R.CURRENCY AND 
DATE(D.CREATED_DATE) = DATE(R.CREATED_DATE) AND
D.COMPLETED IS NULL OR DO.COMPLETED='ABC' AND
D.CURRENCY!='RUPEE';

在查询工作正常之前,但随着表的增长,这个查询开始花费更多时间,而且它以数十亿的方式提供了cartesion产品。

有什么办法可以优化这个查询吗? 任何帮助都会受到极大关注。

2 个答案:

答案 0 :(得分:1)

使用显式join并使用括号修复where子句:

UPDATE DETAILS D JOIN
       RATE R 
       ON D.CURRENCY=R.CURRENCY AND 
          DATE(D.CREATED_DATE) = DATE(R.CREATED_DATE)
  SET D.PRICE1 = D.PRICE1*R.RATE,
      D.PRICE2 = D.PRICE2*R.RATE,
      D.PRICE3 = D.PRICE3*R.RATE
WHERE (D.COMPLETED IS NULL OR DO.COMPLETED='ABC') AND
      D.CURRENCY <> 'RUPEE';

问题是where子句中的括号。但是,您不应该使用逗号来表示join

答案 1 :(得分:0)

DATE(D.CREATED_DATE) = DATE(R.CREATED_DATE)

由于这些字段是DATE数据类型,因此无需使用DATE()函数。实际上,这样做会阻止使用索引。

至少将INDEX(currency, created_date)添加到RATE。加上上述更改将大大加快查询速度。

另一项改进是将currency设为ENUM或将其标准化。