我有一个Product表,该表不断添加具有product_id和price的行。它具有数百万行。
它具有product_id作为主键,如下所示。
CREATE TABLE ProductPrice(
product_id VARCHAR2(10),
prod_date DATE ,
price NUMBER(8,0) ,
PRIMARY KEY (product_id)
)
现在,它具有数百万行,并且为了获得最新价格,它花费了大量时间。
因此,为了管理最新价格,我创建了另一个表,该表将仅保留具有相同格式的最新价格。
CREATE TABLE ProductPriceLatest(
product_id VARCHAR2(10),
prod_date DATE ,
price NUMBER(8,0) ,
PRIMARY KEY (product_id)
)
并且在原始表的每个插入上,我都会编写一个触发器来更新此表中的行。
但是我如何在触发器主体中获取新插入的值?
我尝试过这样的事情:
CREATE OR REPLACE TRIGGER TRIG_HISTory
AFTER INSERT
on ProductPriceLatest
FOR EACH ROW
DECLARE
BEGIN
UPDATE latest_price
SET price = NEW.price ,
WHERE product_id = NEW.product_id ;
END;
提前感谢。
您需要使用:new
关键字来区分:old
值。另外,最好使用AFTER
触发器:
CREATE OR REPLACE TRIGGER TRIG_HISTORY
AFTER INSERT ON source_table_name
FOR EACH ROW
DECLARE
BEGIN
MERGE INTO dest_table_name d
USING (select :new.price p, :new.product_id p_id from dual) s
ON (d.product_id = s.p_id)
WHEN MATCHED THEN
UPDATE SET d.price = s.p
WHEN NOT MATCHED THEN
INSERT (price, product_id)
VALUES (s.p, s.p_id);
END;
如果索引正确,从第一张表中获取最新价格应该很快。与尝试维护单独的表相比,在ProductPrice表上构建正确的索引是更好的解决方案。
您的查询以获取最新价格将如下所示。
SELECT p.product_id, p.prod_date, p.price FROM ProductPrice p JOIN ( SELECT product_id, MAX(prod_date) latest_prod_date FROM ProductPrice GROUP BY product_id ) m ON p.product_id = m.product_id AND p.prod_date = m.latest_prod_date WHERE p.product_id = ????
之所以有效,是因为子查询查找每个产品的最新产品日期。然后,它将使用该信息在表中找到向右显示的行。
如果在(product_id, prod_date, price)
上创建复合索引,该查询将运行得几乎快得惊人。这是因为查询计划者可以在O(log n)或更短的时间内找到正确的索引项。
您可以将其变成这样的视图:
CREATE OR REPLACE VIEW ProductPriceLatest AS SELECT p.product_id, p.prod_date, p.price FROM ProductPrice p JOIN ( SELECT product_id, MAX(prod_date) latest_prod_date FROM ProductPrice GROUP BY product_id ) m ON p.product_id = m.product_id AND p.prod_date = m.latest_prod_date;
然后您可以使用如下视图:
SELECT * FROM ProductPriceLatest WHERE product_id = ???
并获得相同的高性能。
这更容易,不易出错,并且与创建单独的表并对其进行维护一样快。顺便说一下,您要创建的表的DBMS行话是物化视图。