UPDATEを使用する際に、適切にロックがかけられない方へ向けた記事です。以下のような悩みをお持ちの方に役立ちます。UPDATEを書くとスロークエリになるこれらのお悩みを解決する方法を提案します。前置きこの記事は、特定の資料を参考にしたものではなく、私が実験して得られた結果を基に書かれたものです。MySQLのロックの内部的な仕組みを深く理解しているわけではありませんが、実用的な記事を目指して執筆しています。間違った情報が含まれている可能性があることをご了承ください。8.0)では挙動が異なる可能性がありますので、その点もご留意ください。2,000,000インデックスは以下の通りです。FALSEでは、idが1〜3のレコードを取得し、ロックするSQLを考えてみます。UPDATE;このクエリでは、id=1,2,3だけがロックされ、id=4は編集や追記が可能です。これが基本的な考え方です。UPDATEを書くときの重要なポイントは、プライマリーキーかユニークキーを使用し、明示的に示されるクエリを書くことです。INDEXして書いても、適切な速度で動作する必要があります。INDEXを常に指定すると安心です。INDEXが採用されますが、絶対ではありませんので、やや不安が残ります。INDEXは、おすすめのインデックスを指示しているだけなので、確実に使ってくれるとは限りません。INDEXを指定すると、意図した範囲にインデックスが貼られます。INDEXが無視されることがありました。その場合は、STRAIGHT_JOINを指定すると、PRIMARYが使われるようになりました。UPDATE;PRIMARY、ユニークではないカラムでのロックインデックスのないカラムで条件を絞り込みたい場合はどうすれば良いでしょうか?検索条件が、いつもPRIMARYキーがユニークキーであるとは限りません。購入金額には、現時点では何もインデックスを張っていません。UPDATE;このクエリでは、適切なインデックスがないため、全行がロックされてしまいます。修正案としては下記の2パターンが考えられます。UPDATEの効力はサブクエリ内には及びません。そのため、条件取得用のサブクエリとロック用の外側クエリを分けることで、適切な範囲をロックできます。IN句に指定する方法より、FROM句に指定する方法の方が、LIMITが使えるためおすすめです。UPDATE;このようにして、適切な範囲をロックすることで、効率的なクエリを実行することができます。JOINは、あってもなくても取得される結果は同じです。ロック範囲を指定するだけのためにJOINをしています。UPDATEを使用する際には、プライマリーキーやユニークキーを明示的に使用すること、インデックスを適切に指定することが重要です。適切なインデックスを使用することで、意図しないロックやパフォーマンス低下を避けることができます。JOINやサブクエリを使用する場合は、クエリの工夫によって効率的にロックをかけることが可能です。KEYに対してロックをかけることができれば、概ね安心だと考えています。この記事が、皆さんのMySQLでのロック処理の改善に役立つことを願っています。