2008-09-23 3 views
1

게임에서 도시에 대한 정보를 보유한 테이블이 있습니다. 각 턴마다 하나의 건물을 만들 수 있으며,이 값은 "usedBuilding"값과 함께 기록됩니다.맹목적으로 업데이트하거나 Update Where?

각 턴마다 usedBuilding을 0으로 변경하는 스크립트를 실행합니다. 질문은 다음 두 가지 방법 중 어느 것이 더 빠르며 실제로 어떤 방식으로 사용되는지가 중요합니까?

UPDATE cities SET usedBuilding = 0; 
UPDATE cities SET usedBuilding = 0 WHERE usedBuilding = 1; 

답변

4

일반적으로 두 번째 사례 (WHERE 절 포함)는 더 빠릅니다. 사용되지 않는 행에 대해 트리거 평가, 트랜잭션 로깅, 인덱스 업데이트 등을 일으키지 않으므로 더 빠릅니다.

잠재적으로 0/1 값의 분포에 따라 비교를 수행하는 대신 모든 행을 업데이트하는 것이 실제로 빠를 수 있지만 상당히 퇴행성이 있습니다.

쿼리 비용의 ~ 95 %가 I/O이므로 WHERE 절을 사용하면 아무런 차이가 없으므로 (열이 인덱싱되지 않고 테이블 스캔을하고 있기 때문에) 큰 차이가 발생합니다 (열이 인덱싱되거나 테이블이 분할 된 경우 등). 어느 쪽이든, 그것은 상처를주지 않습니다.

당신이 말하는 데이터의 양에 따라 실행 계획이나 속도면에서 차이가 없음을 알 수 있습니다.이 점이 최고 수준의 학업 성취, 최악의 조기 최적화입니다. 그래서, 논리적으로 귀하의 애플 리케이션에 대한 이해가 무엇이든 함께 갈 것을 권 해드립니다.

3

usedBuilding 색인 경우, usedBuilding 사실 전용 액세스/업데이트 행이 어디부터 어디 절을 사용하는 것이 더 빠를 것입니다. 색인이 생성되지 않으면 어쨌든 전체 표 스캔을 수행하므로 많은 차이를 만들 수는 없습니다.

1

"UPDATE cities SET usedBuilding = 0;"을 만드는 데 더 적은 수의 트랜잭션이있는 것처럼 보입니다. 더 구체적인 쿼리보다 실행됩니다. 이 문제에 대해 내가 생각할 수있는 주된 이유는 칼럼에 둘 이상의 상태가있는 경우 일 것입니다. 그저 부울 값이면 괜찮을 것입니다. 그러나 항상 그렇다면 생각하면 시간을 보내고 싶을 것입니다.

인덱싱을 사용하면 WHERE 절을 사용하여 실행 계획을보다 효율적으로 만들 수 있습니다.

1

확실한 답을 얻는 가장 좋은 방법은 다양한 시나리오에서 많은 샘플 데이터를 사용하여 프로파일 링하는 것입니다.

3

수천 번 루프에서 두 가지 방법을 시도하고 시간을 측정하십시오. 아마도이 테이블에있는 레코드의 수와 메모리에 모두 들어 있는지 또는 디스크로 페이징해야하는지에 따라 달라집니다. 업데이트를 실행하기 전에 가치가 1 인 건물이 몇 개인 지 (이 경우 1 일 수 있음).

어떤 방식 으로든 상관 없지만 가장 짧은 것은 잘못 입력했을 가능성이 가장 적습니다. 작성하지 않은 코드에는 버그가 없습니다.

+1

"전통"프로파일 링을 걱정하지 않는다는 RDBMS의 땅에서 쓸모없는 것보다 일반적으로 적습니다. 맹목적인 타이밍보다는 쿼리 계획 및 통계를 살펴야합니다. 또한 일반적으로 RDBMS에 제공 할 수있는 * more * 데이터가 있으면 더 나은 최적화가 사용자를 대신하여 수행 할 수 있습니다. –

1

어쩌면 2 %의 usedBuilding = 1 값을 갖지 않는 한 색인 생성은 전혀 도움이되지 않습니다.

그러나이 두 문장은 논리적으로 다르며 완전히 다른 것을 의미 할 수 있습니다. 하지만 귀하의 경우 동일한 경우 where 절없이 하나를 사용하십시오.

2

얼마나 자주 이러한 전환이 발생합니까? 이 테이블에 몇 개의 행이 있습니까? 대답이 '1 초 미만'과 '10000 미만'인 경우 걱정하지 마세요.

물론 이런 일에 학문적 관심이있는 경우가 아니라면.

1

정확히 얼마나 많은 행이 있습니까? 나는 작은 온라인 게임에 대해 당신이 정말로 신경 쓰지 않는다고 생각합니다.

"cities"테이블을 여러 번 업데이트하는 경우 가능한 경우 하나의 UPDATE 문에서 모두 수행하는 것이 좋습니다.

행을 변경하면 인덱스 행을 업데이트하는 과정을 제외하고 전체 행을 쓰는 것만 큼 많은 I/O가 필요하므로 많은 수의 행을 띄운 몇 가지 UPDATE를 만들어 잃게됩니다.

그러나 당신이있는 경우에, 말, < 1000 행, 당신이 정말로 :)