我们正在考虑对以下内容进行SQL查询:
UPDATE tableA SET columnA = columnB WHERE columnA = 0 LIMIT 1000
tableA有10亿行和columnA上的索引。 columnB是一个高度选择性的数据。
1)这个表现有多糟糕?它正在查询正在更新的索引这一事实是否会导致对索引的某种阻塞?或者在进行更新之前,查询是否会先完成?
2)由于此表有十亿行,并且我们一次将其限制为1000行,因此此查询将进行多次迭代。 columnA最初为0,我确信在开始部分,它将进行表扫描。但是随着更新的进行,并且当columnA被更多选择性的columnB数据填充时,索引是否会帮助查询,或者只是删除索引并让它进行表扫描更好?
答案 0 :(得分:0)
假设InnoDB,正在更新的行将获得独占(写)锁。这意味着其他SELECT
查询仍然可以读取记录,但是对需要排它锁(更新查询)的记录的任何查询都将阻塞,直到锁被释放(事务/查询结束)。
此外,在查询(事务)完成之前,任何SELECT
个查询都会看到旧值。
您可能正确使用索引进行选择。如果您有更新的MySQL版本,您应该能够在更新查询上执行EXPLAIN
以查看它是否将使用索引。 LIMIT
子句通常不在查询优化中考虑,因此在有0的记录数量显着减少之前,索引将用于满足搜索。
但是,由于您比MySQL更了解查询,并了解实际需要的查找数量有限(LIMIT
子句),因此您可以强制使用UPDATE
中的索引:
UPDATE tableA FORCE INDEX (idx_columnA)
SET columnA = columnB WHERE columnA = 0 LIMIT 1000