2011-05-26 95 views
2

我使用mysql來更新表中的一個字段,當條件滿足時...Mysql更新之前首先檢查是否有必要或只是更新?

我應該首先做一個SELECT來查看條件是否滿足或者我只是嘗試每次都使用UPDATE,因爲如果條件不符合,什麼都不會發生。

要具體,這是我的選擇:

SELECT * FROM forum_subscriptions 
WHERE IDTopic=11111 AND IDUser=11111 and status=0 

我檢查在這裏如果我在論壇主題11111,如果,如果我(用戶ID 1)訂購這一主題,我的狀態訂閱爲0(這意味着他並沒有收到電子郵件有關話題的新職位)

所以,當這滿足做:

UPDATE forum_subscriptions SET Status=1 where IDTopic=11111 AND IDUser=1 

現在我想知道,我總是做一個選擇這裏詢問如果用戶訂閱了這個主題,並且他有一個他訪問該主題的狀態,那麼任何新帖子都不會觸發新的電子郵件通知。當他再次訪問該頁面時,會觸發更新以重置訪問,以便任何新帖子將再次向他發送電子郵件。

因此,如果每個用戶訂閱或不測試訂閱,則選擇每個用戶。只有在必要時才進行更新。

使用更新更好嗎?要嘗試在每個頁面上更新,如果他沒有訂閱該主題,它將不會更新任何內容。

更新不會產生任何有效數據的速度有多快?內部是如何製作的,更新如何查找是否有任何記錄,它是否選擇並更新?如果是這樣,只更新會更好,因爲我會在不減速的情況下實現同樣的目標。如果更新比選擇更貴,我應該先嚐試檢查,然後根據需要進行更新。

這個例子是一個真實的例子,但是這個更新/ select的邏輯實際上是我感興趣的,因爲我更經常發現這種類型的問題。

感謝名單

UPDATE:感謝名單都可以的,但我不上你的鏈接看是否更新鎖定,即使沒有結果還是不行。當你給出不同的答案時,我仍然不知道該怎麼做。

訂閱表實際上不需要是myisam,我可以將它更改爲InnoDB,因爲我不需要全文。這是一個很好的解決方案,只使用更新並將此小表更改爲inno?混合表類型有什麼缺點?

+0

語句條件是你是問關於'InnoDB'或'MyISAM'表? – 2011-05-26 15:29:48

+0

我使用myISAM表,但我想我可以使用這個訂閱表是INNODB,因爲我不需要全文...它是否聰明將其更改爲innodb並僅使用更新? – Jerry2 2011-05-26 16:11:09

回答

2

你只是更新,沒有以前的選擇:

UPDATE forum_subscriptions SET Status=1 where IDTopic=11111 AND IDUser=1 

如果條件得不到滿足,更新不會做任何事情。
這個更新是非常快的如果你有一個索引statusIDtopicIDuser
空更新與空選擇一樣快。

如果你先選擇,你會無緣無故地放慢速度。

如果你想知道有多少行,其中更新做

SELECT ROW_COUNT() as rows_affected 

做更新後,這會告訴你0,如果沒有行,其中更新或更新(或插入的行數或刪除,如果你使用這些語句)
這個功能超快,因爲它只需要從內存中獲取一個值。

解決方法表鎖定問題

在這裏看到:總是調用UPDATEhttp://dev.mysql.com/doc/refman/5.5/en/table-locking.html

+0

Thanx很多,所以更新本身,如果首先作出選擇,看看是否更新?我的意思是,不是訂戶的用戶不會因爲此更新聲明而真正鎖定myisam表? – Jerry2 2011-05-26 15:32:45

+0

我在哪裏做SELECT ROW_COUNT()?更新後?如果在兩次查詢之間發生另一次更新會怎麼樣? – Jerry2 2011-05-26 15:35:08

+0

Thanx的更新。但是,如果在網站上某處發生了其他更新,我會得到一個錯誤的ROW_COUNT()? – Jerry2 2011-05-26 15:37:51

1

潛在側影響是一個需要投入,以確保沒有其他連接修改這些行鎖定。

  • 如果表格爲MyISAM - 在搜索過程中會在整個表格上放置鎖定。
  • 如果該表爲InnoDB,鎖定將位於索引/間隙中。

Docs

鎖定讀,一個UPDATE,或與該SQL語句的 處理掃描每 索引記錄DELETE 一般設置記錄鎖。它 不要緊是否有 WHERE在 將排除行

+0

因此,即使結果爲空,大多數情況下都會執行鎖定操作?這實際上是一個如何在MySQL 5.6內部進行更新的問題。它是否首先選擇,如果它發現它更新的記錄,或者它只是試圖更新和鎖定,即使沒有記錄。 – Jerry2 2011-05-26 15:33:56

+0

@ jerry2是的。如果您正在使用'InnoDB'表並且設計了合適的索引,那應該不成問題。 – 2011-05-26 15:36:37

+0

@ jerry2在需要更新記錄的* search *期間放置鎖。 – 2011-05-26 15:37:14