TSQL:을 선택하면 부모에 따라 조건에 아동

0

질문

나는 부모 테이블 Orders 그리고 아이블 Jobs 다음 샘플 데이터 enter image description here

I 을 선택하려 주문에 따라 다음과 같은 요구사항

1>각 주문에 대한될 수 있습 0 거나 더 작업입니다. 선택하지 않기 위해 있지 않은 경우 모든 작업입니다.
2>사용자에서 작업할 수 없습니다 더 이상 하나의 작업에 속하는 동일한다.
예를 들어 사용자 1 에서 작업할 수 없습니다 작업에 속하는 순서 1 및 2 기 때문에 그는 이미 일에 작업 14 에서 같은 순서입니다.
3>만 선택 명령이 있는 작업 Requested 상태

나는 다음과 같은 쿼리에는 예상된 결과

DECLARE @UserID INT = 2

SELECT O.OrderID
FROM Orders O
JOIN Jobs J ON J.OrderID = O.OrderID
WHERE 
J.JobStatus = 'Requested' AND
NOT EXISTS
(  
    --Must not have worked this Order
    SELECT 1 FROM Jobs J1
    WHERE J1.OrderID = O.OrderID AND J1.UserID = @UserID
)
Group By o.OrderID

SQL 데모 바이올린

쿼리인 Jobs 테이블에 두 번. 내가 노력하고 최적화하는 쿼리를 찾고있는 방법을 달성하는 예상된 결과를 사용하여 Jobs 테이블만 일단 가능한 경우. 다른 솔루션은 감사합니다. 나는 바꿀 수 있는 테이블 스키마는 경우 필요합니다.

작업 테이블이있는 거의 20M 행과 약간의 시간 쿼리를 보여주는 가난한 성과입니다. (예,우리는 인덱스). 내가 생각하의 스캐닝 작업 테이블은 두 번 일으키는 성능 문제입니다.

2

최고의 응답

1

는 경우 목표로 그냥"사용 작업 테이블 단면"나는 것입하려고 다음과 같습니다.

DECLARE @UserID INT = 2
    
SELECT 
    O.OrderID
FROM 
    Orders O
    INNER JOIN Jobs J ON J.OrderID = O.OrderID  
GROUP BY
    O.OrderID
HAVING
    SUM(CASE WHEN J.JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN J.UserID = @UserId THEN 1 ELSE 0 END) = 0

SQL 바이올린

을 최적화하는,더 나는 것이 좋 교체 varchar 의 데이터 형식 JobStatustinyint 중 하나(그리고 만들기 JobStatuses 테이블). 면 Job 테이블 20M 레코드를,다음 varchar(10) 제 190Mb 그러나 사용 tinyint 을 줄일 수 열의 크기는 19Mb—이것은 당신이 덜 IO 읽는 작업입니다.

그리도록 노력하겠다 아이를 분리하는 필터링에 합류에서 그것은 부모에게 있습니다. 이러한 접근 방식을 사용할 수 있는 적은 메모리를 위한 하나의 작업에서 승리하기 때문에 성능의는:

DECLARE @UserID INT = 2
DECLARE @OrderIDs TABLE (OrderID INT NOT NULL PRIMARY KEY)

INSERT IGNORE INTO @OrderIDs
SELECT
    OrderID
FROM
    Jobs
GROUP BY
    OrderID
HAVING
    SUM(CASE WHEN JobStatus = 'Requested' THEN 1 ELSE 0 END) > 0
    AND SUM(CASE WHEN UserID = @UserId THEN 1 ELSE 0 END) = 0

SELECT
    O.*
FROM
    Orders O
    INNER JOIN @OrderIDs ids on ids.OrderID = O.OrderID
2021-11-16 09:14:13

작업 상태를 실제로 ID 의 유형 int. 단지에 대한 이해를 목적을 유지했으로 이며
LP13

이 방법을 찾아 나는 심지어를 함께 주문이다. 내가 직접 사용할 수 있습니다 작업 테이블을 얻으십시오
LP13
0

고려할 수 있습니다 추가하는 다음을 인덱스 Jobs 테이블:

CREATE INDEX idx_jobs ON Jobs (OrderID, UserID, JobStatus);

이 지는 경우 사용해야 속도 존재하지 않는 하위에서 쿼리를니다. 또한,그것을 위해 사용될 수 있습에 참여 Orders 하기 Jobs 외부에서 최고 수준의 쿼리로더(SQL 서버는 아마 할 일이 index scan).

2021-11-16 08:40:46

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................