当在非唯一索引列上执行UPDATE和WHERE时,表行的上下文中的规则是如何遇到的?
我有一个测试表,其中col列为非唯一索引:
id | col
----------
1 | 1
----------
2 | 2
----------
3 | 2
----------
22 | 3
UPDATE tab SET col=1 WHERE col=1;
// OR
UPDATE tab SET col=3 WHERE col=3;
// OR
UPDATE tab SET col=2 WHERE col=2;
// These updates encounter ONLY rows where col=1, col=3 or col=2
相同的表和相同的更新,但在表格中还有一个记录,其中col = 2:
id | col
----------
1 | 1
----------
2 | 2
----------
3 | 2
----------
4 | 2
----------
22 | 3
UPDATE tab SET col=1 WHERE col=1;
// OR
UPDATE tab SET col=3 WHERE col=3;
// Both updates encounter ONLY rows where col=1 or col=3.
UPDATE tab SET col=2 WHERE col=2;
// This update encounters ALL the rows in the table even those where col IS NOT 2.
// WHY ?
答案 0 :(得分:0)
那里有一篇精彩的文章。我相信这会回答你的疑问。
http://www.mysqlperformanceblog.com/2012/11/23/full-table-scan-vs-full-index-scan-performance/
答案 1 :(得分:0)
简而言之,处理UPDATE
时遇到的每一行都是行锁定的。这意味着UPDATE
的锁定影响取决于如何处理查询以读取要更新的行。如果您的UPDATE
查询不使用索引或错误索引,则可能会锁定许多或所有行。 (请注意,锁定行的订单还取决于所使用的索引。)在您的情况下,由于您的表格非常小,而且您实际上正在改变您的行的分布索引,它选择对相关查询使用全表扫描。
您可以测试大多数UPDATE
个查询的效果和行为,方法是将它们转换为SELECT
并在其上使用EXPLAIN SELECT
(在较新的版本中,您甚至可以EXPLAIN UPDATE
)
简而言之:在测试性能或锁定行为之前,您应该拥有具有实际数据分布的表,而不是具有少量测试行的非常小的表。