2013-08-28 2 views
1

postgres가 주문한 결과가 일관되게 정렬되지 않는 문제가 있습니다. 여러 필드로 주문하고 있습니다 : ORDER BY categories.position ASC, photos.display_priorityPostgres 순서가 일치하지 않습니다.

사이트를 탐색 할 때마다 결과가 페이지 매김을하기 때문에 눈치 챘을 것입니다. 나는 2 페이지를 1 페이지에서 이동 사례를 발견했고, 2 페이지의 상단에 나는 여기에

페이지에서 1. 하단이었다 사진 1 개 쿼리 내 페이지입니다 참조 :

SELECT "photos".* 
FROM "photos" 
    INNER JOIN "categories" ON "categories"."id" = "photos"."category_id" 
WHERE "photos"."category_id" IN (221, 633, 377, 216, 634) 
    AND (photos.caption IS NOT NULL 
     AND photos.category_id IS NOT NULL 
     AND photos.rights IS NOT NULL 
     AND photos.deleted IS NULL) 
ORDER BY categories.position ASC, photos.display_priority DESC 
LIMIT 25 OFFSET 0; 

그리고 내 2 페이지 쿼리 : 나는 한 번에 두 페이지를 받고하려고하면

SELECT "photos".* 
FROM "photos" 
    INNER JOIN "categories" ON "categories"."id" = "photos"."category_id" 
WHERE "photos"."category_id" IN (221, 633, 377, 216, 634) 
    AND (photos.caption IS NOT NULL 
     AND photos.category_id IS NOT NULL 
     AND photos.rights IS NOT NULL 
     AND photos.deleted IS NULL) 
ORDER BY categories.position ASC, photos.display_priority DESC 
LIMIT 25 OFFSET 25; 

가 (0, 오프셋 (50)을 제한) 및 중복, 놀라운 일이없는 두 세트 사이의 임계 값을 검사합니다.

SELECT "photos".* 
FROM "photos" 
    INNER JOIN "categories" ON "categories"."id" = "photos"."category_id" 
WHERE "photos"."category_id" IN (221, 633, 377, 216, 634) 
    AND (photos.caption IS NOT NULL 
     AND photos.category_id IS NOT NULL 
     AND photos.rights IS NOT NULL 
     AND photos.deleted IS NULL) 
ORDER BY categories.position ASC, photos.display_priority DESC 
LIMIT 50 OFFSET 0; 

내 검색어에 문제가 있습니까? 내가 이해하지 못하는 한도와 질서가있는 명령이 있습니까?

답변

5

categories.positionphotos.display_priority은 모든 결과 행에 고유하지 않은 것으로 들립니다. 데이터베이스 서 v는 행 순서를 지정하는 데 사용 된 값이 모두 같을 때 행의 순서를 지정하지 않습니다. 쿼리간에 테이블 데이터가 변경되지 않은 경우에도 임의의 순서로 자유롭게 반환 할 수 있습니다.

일관된 정렬을 얻으려면 특정 행에 대한 ID 값과 같이 모든 행에 대해 고유해야하는 세 번째 정렬 키를 추가해야합니다.

+0

네가 맞아. 그것이 원인이었습니다. 이상한. 나는 그 결과의 순서가 무작위가된다는 것을 알지만, 여전히 일관성이 있다고 생각했다. 나는 하나의 질의에서 그 순서가 변경 될 오프셋을 변경하는 다음 쿼리까지 상상할 수 없었습니다. 어쨌든, 도와 줘서 고마워! –

+0

@KeithSchacht 문제가 없습니다. 행이 재정렬 된 이유는 기본 테이블이 변경 되었기 때문일 수 있습니다. 행이 반환되는 순서에 영향을 줄 수있는 많은 요소가 있습니다. 데이터 집합의 맨 끝에 하나의 행이 추가 되더라도 (순서대로) 다른 행이 정렬되는 방식에 영향을 줄 수 있습니다. 데이터 자체를 변경하지 않고 간단히 (VACUUM FULL 또는 CLUSTER와 같이) 데이터를 변경하지 않는 다른 연산은 동일한 순서의 행이 서로 상대적으로 정렬되는 방식을 변경합니다. 궁극적으로 동일한 주문 행의 일관된 순서를 추정 할 수 없습니다. :) – cdhowie

+0

원칙적으로 주문이 바뀔 수 있습니다. 이 경우 기괴한 것은 그것이 재현 가능하다는 것입니다. 이 특정 쿼리의 경우 첫 번째 페이지 제한을 수행 할 때마다 한 가지 방법이며 두 번째 페이지를 수행 할 때마다 다른 방식으로 정렬됩니다. 그 사이에 DB를 변경하지 않았습니다. 나는 그것이 근본적인 SQL 엔진 최적화 일 것이라고 확신하지만 이것은 앱을 개발할 때 명심해야 할 좋은 교훈이다. –

관련 문제