Mysql
為什麼事務阻塞 MySQL 中的簡單插入?
交易查詢
mysqli_begin_transaction($conn); $sql = "UPDATE foldertable SET trashed = 1 WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? limit 1) and (folderId = ? or RootFolderPath LIKE CONCAT ( (SELECT RootFolderPath FROM foldertable WHERE serverToken = (SELECT serverToken from servertoken where userToken = ? ) AND folderid = ? limit 1) ,'/' , ? ,'%' ) )"; $stmt = mysqli_stmt_init($conn); mysqli_stmt_prepare($stmt, $sql); mysqli_stmt_bind_param($stmt, "sisii", $data["userToken"], $id, $data["userToken"], $id, $id); if (!mysqli_stmt_execute($stmt)) { echo mysqli_stmt_error($stmt); $serverError = true; return; } // echo "\n\n affected rows " . mysqli_affected_rows($conn); if (mysqli_affected_rows($conn) > 0) { sleep(15); // Insert into bin folder $sql = "INSERT INTO binfolder (serverToken , folderId) value ( (SELECT serverToken from servertoken where userToken = ? limit 1) , ?)"; $stmt = mysqli_stmt_init($conn); mysqli_stmt_prepare($stmt, $sql); mysqli_stmt_bind_param($stmt, "si", $data["userToken"], $id); if (!mysqli_stmt_execute($stmt)) { echo mysqli_stmt_error($stmt); $serverError = true; return; } if (mysqli_affected_rows($conn) > 0) { $success = true; mysqli_commit($conn); } }
插入查詢
INSERT INTO foldertable(serverToken) SELECT (123456)
問題
如果在事務開始後執行插入查詢,但插入不必等待事務完成。因為事務上的更新查詢確實鎖定了插入查詢所涉及的行。
我想要的
如果插入查詢不包含
serverToken
插入查詢所需的內容,則插入查詢將立即執行。先感謝您。
對於事務阻塞,第一道防線是加快查詢速度。雖然這並不能完全消除阻塞/延遲/死鎖的可能性,但它通常會使情況更容易忍受。
重新
LIMIT 1
——只有1個嗎?如果是這樣,為什麼不做一個JOIN
. 或者可能不止一個?如果有,是哪一個?也就是說,你不需要一個ORDER BY
?
servertoken
需要INDEX(userToken, serverToken)
一個
INSERT ... ON DUPLICATE KEY UPDATE ...
就足以滿足您冗長的查詢集嗎?如果是這樣,它可能會快很多。我
OR
在長查詢中看到一個。這可能會阻止索引的使用。(我不太了解查詢的意圖,無法提出替代方案。)“RootFolderPath LIKE CONCAT (…” - 這聞起來像是應該重新設計的東西。考慮將路徑部分放在單獨的列中?或其他東西。
是嗎?
folderId
_PRIMARY KEY``folderTable
請為每個相關表格提供
SHOW CREATE TABLE
(作為文本,而不是圖像)。