我正在尝试确定MySQL更新索引的情况.说我有下表:
CREATE TABLE MyTable (
ID INT NOT NULL AUTO_INCREMENT,
MyIndexedColumn VARCHAR NOT NULL,
MyNonIndexedColumn VARCHAR,
PRIMARY KEY (ID),
INDEX MyNewIndex(MyIndexedColumn)
)
Run Code Online (Sandbox Code Playgroud)
然后我运行以下SQL来插入一行:
INSERT INTO MyTable (MyIndexedColumn, MyNonIndexedColumn)
VALUES ('MyTestValue', 'MyTestValue');
Run Code Online (Sandbox Code Playgroud)
据我所知,这个查询会在MySQL中为B-Tree索引添加某种哈希键,用于值'MyTestValue'.
现在,如果我运行以下语句,即使我没有更改列的值,是否会强制更新B-Tree索引?
UPDATE MyTable SET MyIndexedColumn = 'MyTestValue',
MyNonIndexedColumn = 'A New Value' WHERE ID = 1;
Run Code Online (Sandbox Code Playgroud)
MySQL足够聪明,可以确定吗?或者只是将该列作为更新语句的一部分,我告诉MySQL可能已经发生了变化,它应该做更新索引的工作吗?
小智 7
我做了一些测试,用mysql 5.0.41,比较两个相同的innodb表(7个cols,所有整数)的更新,除了一个表有5个索引(其中一个是2列),另一个表没有索引.(但每个表都有其主键索引.)
这是我最终得到的结果(没有索引的表是A,索引的表是B):
10k updates of an indexed column with a new value:
A: 76.8 seconds
B: 126.7 seconds
10k updates of a non-indexed column with a new value:
A: 27.6 seconds
B: 22.0 seconds
10k updates of a random column with its same value:
A: 1.4 seconds
B: 1.2 seconds
10k updates of a random column with an incremented value:
A: 12.2 seconds
B: 50.0 seconds
10k updates of an indexed column=>same value, non-indexed column=>new value:
A: 7.0 seconds
B: 10.5 seconds
Run Code Online (Sandbox Code Playgroud)
我假设相同/递增的值更快的部分原因是因为我必须在执行更新之前查找该行,因此它将以某种形式缓存在mysql中.
这几乎可以说明其他人所说的内容,但是会对索引影响的程度提供一些看法.然而,在Jim询问的具体案例中,看起来它可能会慢50%.
如果您在 MySQL 客户端中运行该查询,您将看到类似的内容
匹配行数:1,更新行数:0
所以 MySQL 肯定知道一行何时发生变化 - 我认为它们足够聪明,不会从那里更新索引。