다음과 같은 테이블 구조가 있다고 가정하십시오.
LogId | ProductId | FromPositionId | ToPositionId | Date | Quantity
-----------------------------------------------------------------------------------
1 | 123 | 0 | 10002 | 2018-01-01 08:10:22 | 5
2 | 123 | 0 | 10003 | 2018-01-03 15:15:10 | 9
3 | 123 | 10002 | 10004 | 2018-01-07 21:08:56 | 3
4 | 123 | 10004 | 0 | 2018-02-09 10:03:23 | 1
FromPositionId
및 ToPositionId
재고 위치입니다. 예를 들어 일부 위치 ID는 특별한 의미가 있습니다 0
. 또는 이벤트는 0
주식이 생성 또는 제거되었음을 나타냅니다. From 0
은 납품에서 재고가 0
될 수 있고 선적 된 주문이 될 수 있습니다.
이 테이블에는 현재 약 550 만 개의 행이 있습니다. 다음과 같은 쿼리를 사용하여 각 제품의 재고 값을 계산하고 일정에 따라 캐시 테이블에 배치합니다.
WITH t AS
(
SELECT ToPositionId AS PositionId, SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY ToPositionId, ProductId
UNION
SELECT FromPositionId AS PositionId, -SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY FromPositionId, ProductId
)
SELECT t.ProductId, t.PositionId, SUM(t.Quantity) AS Quantity
FROM t
WHERE NOT t.PositionId = 0
GROUP BY t.ProductId, t.PositionId
HAVING SUM(t.Quantity) > 0
이것이 합리적인 시간 (약 20 초)에 완료되었지만 주식 가치를 계산하는 것은 매우 비효율적 인 방법이라고 생각합니다. INSERT
이 표에서 : s 이외의 다른 작업은 거의 없지만 때때로 행을 생성하는 사람들의 실수로 인해 수량을 조정하거나 행을 수동으로 제거합니다.
별도의 테이블에 "체크 포인트"를 생성하고 특정 시점까지의 값을 계산하고 주식 수량 캐시 테이블을 생성 할 때이를 시작 값으로 사용하는 아이디어가있었습니다.
ProductId | PositionId | Date | Quantity
-------------------------------------------------------
123 | 10002 | 2018-01-07 21:08:56 | 2
때때로 행을 변경한다는 사실은 이것에 문제가되며,이 경우 변경된 로그 행 이후에 생성 된 모든 검사 점을 제거해야합니다. 이것은 지금까지 검사 점을 계산하지 않고 해결할 수 있지만 지금과 마지막 검사 점 사이에 한 달을 남겨 두십시오 (우리는 그다지 거의 변경하지 않습니다).
때때로 행을 변경해야한다는 사실을 피하기가 어렵고 여전히이 작업을 수행 할 수 있기를 원합니다.이 구조에는 표시되지 않지만 로그 이벤트는 때로는 다른 테이블의 다른 레코드와 연결되고 다른 로그 행을 추가합니다 올바른 수량을 얻는 것은 때때로 불가능합니다.
로그 테이블은 상상할 수 있듯이 꽤 빠르게 성장하며 계산 시간은 시간이 지남에 따라 증가합니다.
내 질문에, 당신은 이것을 어떻게 해결할 것입니까? 현재 주식 가치를 계산하는 더 효율적인 방법이 있습니까? 체크 포인트에 대한 나의 아이디어는 좋은 것인가?
SQL Server 2014 Web (12.0.5511)을 실행 중입니다.
실행 계획 : https://www.brentozar.com/pastetheplan/?id=Bk8gyc68Q
실제로 위의 잘못된 실행 시간을 주었다. 20 초는 캐시의 전체 업데이트에 걸린 시간이었다. 이 쿼리는 실행하는 데 약 6-10 초가 걸립니다 (이 쿼리 계획을 만들 때 8 초). 이 질문에는 원래 질문에 포함되지 않은 조인도 있습니다.