2013-04-30 77 views
0

我有一個來自一個表(FileInstance)的多個SELECT的請求,這些SELECT使用MAX函數。 在此INSERT語句SELECT MAX(Sequence) FROM FileInstance中會給出相同的結果嗎? 是否有可能在這些SELECT之間添加記錄,我會捕獲不同的值?多選請求期間數據是否可以更改?

INSERT INTO 
    FileInstance (Data, Size, FileID, ChangesetID) 
VALUES 
(
    (SELECT Data FROM FileInstance WHERE FileID=%1 AND Sequence=(SELECT MAX(Sequence) FROM FileInstance WHERE FileID=%1)), 
    (SELECT Size FROM FileInstance WHERE FileID=%1 AND Sequence=(SELECT MAX(Sequence) FROM FileInstance WHERE FileID=%1)), 
    %1, 
    NULL 
); 

五言中,我認爲這兩個電話SELECT MAX(序列)FROM FileInstance WHERE =寫到FileID 1%將轉化爲一個呼叫,但我只是想確定。

我使用postgresql 9.2。 謝謝!

回答

2

是的,該語句在數據庫運行時會看到一致的視圖。所以這兩個子選擇都會返回相同的值。

編輯:我想也可能需要關於併發插入的說明。如果某個其他事務在您的語句正在運行時插入更高的序列號,那麼如果序列上有唯一的索引,則可能會導致錯誤。

如果序列列不需要沒有空位,使用real序列可能是更好的解決方案。

如果您想避免併發事務的問題,您可能希望在運行插入之前將隔離級別更改爲「可序列化」。


但是,您的聲明效率很低。這可以簡化爲:

INSERT INTO FileInstance 
    (Data, Size, FileID, ChangesetID) 
SELECT Data, Size, %1, NULL 
FROM FileInstance 
WHERE FileID=%1 
AND Sequence = (SELECT MAX(Sequence) 
       FROM FileInstance 
       WHERE FileID=%1); 

select語句可能會被刪除甚至更快的子選擇與窗函數替換它:

INSERT INTO FileInstance 
    (Data, Size, FileID, ChangesetID) 
select Data, Size, fileID, NULL 
from (
    select data, 
     size, 
     fileid, 
     max(sequence) over (partition by fileId) as max_seq, 
     sequence 
    from fileinstance 
    where fileID = %1 
) t 
where sequence = max_seq; 
+0

謝謝你,並優化了。 – Serhiy 2013-04-30 07:31:17

+0

@Serhiy:請參閱我關於併發事務問題的編輯。 – 2013-04-30 07:34:11

+0

在我的情況下,concurent insert是不可能的,我在其他表中有一個警衛作爲唯一記錄。 – Serhiy 2013-04-30 07:44:04

相關問題