从表A的已过滤部分中选择一个行,其中某列与表B中的行中具有ID匹配关系的列相匹配,

时间:2019-04-18 07:07:07

标签: sql amazon-redshift

我想获取表中的所有行,其中一列与另一表中具有相同值的另一表中该行中该列的值之间的关系相匹配。

具体来说,我有两个表,分别是通过Amazon Redshift访问的订单和product_info

订单

| ID   | Date     | Amount | Region |
=====================================
| 1    | 2019/4/1 | $120   | A      |
| 1    | 2019/4/4 | $100   | A      |
| 2    | 2019/4/2 | $50    | A      |
| 3    | 2019/4/6 | $70    | B      |

顺序的分区键是区域和日期。

产品信息

| ID   | Release Date | Region |
| ---- | ------------ | ------ |
| 1    | 2019/4/2     | A      |
| 2    | 2019/4/3     | A      |
| 3    | 2019/4/5     | B      |

产品信息的主键是id,分区键是地区。

我想从区域A的订单中获取所有行,其中该行的日期大于该ID的产品信息中的发布日期值。

因此在这种情况下,它应该仅返回一行,

| 1    | 2019/4/4 | $100   | A      |

我尝试做

select *
from orders
INNER JOIN product_info ON orders.date>product_info.release_date
  AND orders.id=product_info.id
  AND orders.region=A
  AND product_info.region=A
limit 10

问题在于此查询的速度异常缓慢(10分钟后取消了查询)。这些表非常大,我感觉它正在扫描整个表而没有先将其限制为区域(实际上,除了区域之外,我还有其他过滤器,我想在进行内部联接之前将其应用于ID列表,但为了简化问题,我将其限制在仅区域内。

如何有效编写此类查询?

1 个答案:

答案 0 :(得分:0)

使SQL查询更快的最佳方法是尽快排除行。

因此,不要将诸如orders.region=A之类的条件放入JOIN语句中,而应将其移至WHERE语句中。这样将消除行之间的连接。

另外,使JOIN条件尽可能简单,以便数据库可以优化比较。

尝试这样的事情:

SELECT *
FROM orders
INNER JOIN product_info ON orders.id = product_info.id
WHERE orders.region = 'A'
  AND product_info.region = 'A'
  AND orders.date > product_info.release_date

任何进一步的优化都需要考虑Redshift表上的DISTKEYSORTKEY。 (最好是DISTKEY的{​​{1}}和id的{​​{1}})。