【发布时间】:2014-09-08 13:19:13
【问题描述】:
什么更有效:
START TRANSACTION
UPDATE mytable SET foo = 'bar' WHERE (col1 = 813242) AND (col2 = 25343);
UPDATE mytable SET foo = 'bar' WHERE (col1 = 312643) AND (col2 = 8353);
UPDATE mytable SET foo = 'bar' WHERE (col1 = 843564) AND (col2 = 41233);
UPDATE mytable SET foo = 'bar' WHERE (col1 = 321312) AND (col2 = 5325);
UPDATE mytable SET foo = 'bar' WHERE (col1 = 554235) AND (col2 = 6321);
... x 10,000 times or more
COMMIT;
或
UPDATE mytable SET foo = 'bar' WHERE
((col1 = 16344) AND (col2 = 5456)) OR
((col1 = 42134) AND (col2 = 5436)) OR
((col1 = 84563) AND (col2 = 2321)) OR
((col1 = 43216) AND (col2 = 4267)) OR
((col1 = 53248) AND (col2 = 6234)) OR
... x 10,000 times or more
假设我在 (col1,col2) 上有 UNIQUE 索引
所以我的猜测是第一个选项很好,因为索引但是它被分成多个查询,第二个选项很好,因为它只是一个查询,但另一方面它会进行全表扫描
这是EXPLAIN,当不使用OR时:
type: ref, possible_keys: myindex_UNIQUE, key: myindex_UNIQUE, ref: const
这是EXPLAIN,当使用OR时:
type: ALL, possible_keys: myindex_UNIQUE, key: null, ref: null
查询WHERE子句有限制吗?
我的目标是最大速度
【问题讨论】:
-
所以模式是
col1 = N AND col2 = N+1(即col2 = col1 + 1?这可能是可能的,并且通过连接可能更有效...... -
@MichaelBerkowski 没有模式,这只是一个例子
-
彼得,你是重复 10000 次 UPDATE 语句还是从 START 到 COMMIT 的块?
-
@Peter:我知道这不是直接的答案,但我建议您使用无事务解决方案,如果这是可以接受的并且如果要更新许多记录,则使用单独的 UPDATE 语句每个查询很少。长时间的交易不是好事。
-
Hmmm.. 一种可能的解决方案是将 API 调用的结果插入到临时/帮助表(可能带有索引)中,并将该表用作更新查询的过滤器。如果您的表包含的行数比要更新的行数多得多,这可能会有所帮助。您可以在更新后截断或删除临时/帮助表。临时表可以使用基于内存的存储引擎来最大化性能。
标签: mysql