2013-08-28 26 views
1

我有一個問題,其中postgres命令的結果不是一致排列的。我訂購的多個領域:ORDER BY categories.position ASC,photos.display_priorityPostgres排序不一致

我注意到這一點,因爲當你瀏覽網站的結果分頁。我發現,我從第1頁到第2頁的情況下,在第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不是唯一的所有結果行。當用於排序的值全部相等時,數據庫服務器不會指定行的順序;即使表格數據在查詢之間沒有變化,也可以以任意順序返回它們。

爲了獲得一致的排序,您將不得不添加第三個排序鍵,該排序鍵對於所有行都是唯一的,例如該特定行的標識值。

+0

你說得對。這是原因。奇。我知道這些結果的順序是隨機的,但我認爲它仍然是一致的。我從來沒有想到,從一個查詢到下一個我只是改變偏移量的順序就會改變。無論如何,謝謝你幫助我! –

+0

@KeithSchacht沒問題。行被重新排序的原因可能是因爲底層表發生了變化。有很多因素可能會影響返回行的順序。即使在數據集的最後添加了一行(排序後),也會影響其他行的排序方式。其他不改變數據本身,但只是重新排列它的操作(如'VACUUM FULL'或'CLUSTER')通常會改變具有相同順序的行相對於彼此排列的方式。最終,你不能假定相同順序行的一致排序。 :) – cdhowie

+0

我原則上可以改變排序。在這種情況下奇怪的是它是可重複的。對於這個特定的查詢,每次我做第一頁LIMIT時都是一種方式,每次我進行第二頁LIMIT時,都會按不同的方式進行排序。這與之間的數據庫沒有變化。我相信這只是一些基礎的SQL引擎優化,但這是我在構建應用程序時牢記的一個很好的教訓。 –