[英]Safely auto increment MySQL field based on MAX() subquery upon insert
我有一個表,其中包含標准的自動遞增ID,類型標識符,數字和一些其他不相關的字段。 當我將新對象插入此表時,該數字應根據類型標識符自動遞增。
以下是輸出應如何顯示的示例:
id type_id number
1 1 1
2 1 2
3 2 1
4 1 3
5 3 1
6 3 2
7 1 4
8 2 2
如您所見,每次插入新對象時,數字都會根據type_id遞增(即如果我插入一個type_id為1的對象,並且有5個對象已經匹配此type_id,則新對象上的數字應為6 )。
我試圖通過巨大的並發性來找到一種高效的方法。 例如,對於相同的type_id,同一秒內可能有300個插入,並且需要按順序處理它們。
這是一個糟糕的主意,但我已將其添加為完整性。 請求獲取項類型的MAX()號,然后將數字+ 1作為插入的一部分添加。 這很快但不能同時工作,因為在MAX()請求和特定插入之間可能有200個插入,導致多個對象具有相同的number和type_id。
在每次插入之前和之后手動鎖定和解鎖表,以保持增量。 由於並發插入的數量而導致性能問題,並且因為在整個應用程序中不斷讀取該表。
這就是我目前正在做的事情,但它仍然會導致大量的性能問題:
START TRANSACTION;
INSERT INTO objects (type_id,number) VALUES ($type_id, (SELECT COALESCE(MAX(number),0)+1 FROM objects WHERE type_id = $type_id FOR UPDATE));
COMMIT;
關於這種方法的另一個負面的事情是我需要進行后續查詢以獲得添加的數字(即搜索具有按序號desc排序的$ type_id的對象,以便我可以看到創建的數字 - 這是基於$ user_id完成的,所以它可以工作,但添加了一個額外的查詢,我想避免)
我調查使用觸發器,以便在插入時動態添加數字,但這不是高性能,因為我需要對我插入的表執行查詢(這是不允許的,因此必須在子查詢中性能問題)。
我已經看過分組自動增量(這樣數字會根據type_id自動增加),但后來我丟失了自動增量ID。
有沒有人對如何在我需要的並發插入級別上提高性能有任何想法? 我的表目前是MySQL 5.5上的InnoDB
感謝任何幫助!
更新:萬一它是相關的,對象表中有幾百萬個對象。 一些type_id
可以分配大約500,000個對象。
使用事務並選擇...進行更新。 這將解決並發沖突。
在使用子查詢的事務中
嘗試在列type_id上創建索引
我認為通過在列type_id上創建索引可以加快子查詢的速度。
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,type_id INT NOT NULL
);
INSERT INTO my_table VALUES
(1,1),(2,1),(3,2),(4,1),(5,3),(6,3),(7,1),(8,2);
SELECT x.*
, COUNT(*) rank
FROM my_table x
JOIN my_table y
ON y.type_id = x.type_id
AND y.id <= x.id
GROUP
BY id
ORDER
BY type_id
, rank;
+----+---------+------+
| id | type_id | rank |
+----+---------+------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 4 | 1 | 3 |
| 7 | 1 | 4 |
| 3 | 2 | 1 |
| 8 | 2 | 2 |
| 5 | 3 | 1 |
| 6 | 3 | 2 |
+----+---------+------+
或者,如果性能是一個問題,只需對幾個@variables做同樣的事情。
也許是為所有具有公共“type_id”的行創建(臨時)表的想法。 在該表中,您可以為num colomn使用自動遞增。 然后你的數字應該完全可信。 然后,您可以選擇數據並更新第一個表格。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.