使用日期列上的null子句优化count(*)

问题描述 投票:0回答:1

在我的数据库中,我们将审核信息存储在与当前记录相同的表中。因此,像product_customer这样的表具有4列product_id,customer_id,start_date,end_date,其中product_id,customer_id和开始日期为主键列。每当我们必须终止与客户的产品关联时,我们都会更新该记录的end_date,如果购买了新产品,我们会插入一条具有相应客户和产品ID值的新记录,其中start_date为购买日期,end_date为NULL。

此表现在有将近20年前的6000万条记录,其中大约65%的记录是审计信息。我建议将至少有15年历史的数据移至存档表,但是它与某些保留策略有关,因此必须得到很多人的认可。我当前的Oracle DB版本是10G,但将在几周内迁移到12C。

[有一个新的要求,我们需要返回与特定产品相关的客户数量,但问题是有些产品拥有数百万的客户,因此我编写的查询要花费很多时间(有时20分钟)执行。

SELECT count(customer_id)
FROM product_customer
WHERE product_id = i_product_id AND end_date IS NULL;

由于我们正在迁移到Oracle 12c,有没有一种方法可以加快此查询的速度(我读到B-Tree索引不索引空值,所以位图索引可以索引,但是由于此表上运行着非常频繁的DML语句, ,我认为位图索引在这里不起作用)。

请您帮忙。

sql oracle query-performance
1个回答
0
投票

您的查询应该能够利用product_customer(product_id, end_date)上的索引。

但是,即使扫描具有6000万行的表也不需要20分钟。其他事物可能会干扰,例如:

  • 系统上的其他进程锁定记录/表。
  • 使用视图而不是表。

我还将指出,在这种情况下,我看到许多系统(尤其是Oracle)使用的是“无限”结束日期,而不是NULLDATE '4195-01-01'似乎很受欢迎;我不知道这是本地化还是更普遍。

© www.soinside.com 2019 - 2024. All rights reserved.