mysql myisam 引擎中的主键是否隐式存储在其他键中?
Is the primary key stored implicitly in other keys in mysql myisam engine?
我的问题:想象一个有数百万行的 table,比如
CREATE TABLE a {
id INT PRIMARY KEY,
column2..,
column3..,
many other columns..
..
INDEX (column2);
和这样的查询:
SELECT id FROM a WHERE column2 > 10000 LIMIT 1000 OFFSET 5000;
我的问题:mysql 只使用索引 "column2"(因此主键 id 隐式存储为其他索引中的引用),还是必须获取所有行才能获取还有选择用于输出的id?在那种情况下,使用声明为的键查询应该快得多:
INDEX column2(column2, id)
需要 column2
上的索引。您在索引中使用 id 的建议将阻止 table 扫描并且应该非常有效。
此外,假设 column2
是一个连续序列,这样做会更快:
SELECT id FROM a WHERE column2 > 15000 LIMIT 1000;
这是因为要使用偏移量,它只需扫描接下来的 5000 条记录(MySQL 没有意识到您实际上正在偏移 column2
)。
简答:否
长答案:
MyISAM与InnoDB不同,对每个索引的叶子节点中的数据有一个"pointer",包括那个PRIMARY KEY
.
所以,INDEX(col2)
本质上是 INDEX(col2, ptr)
。 INDEX(id)
的同上是 INDEX(id, ptr)
。
"pointer" 是 .MYD 文件中的字节偏移量(DYNAMIC
)或记录号(FIXED
)。在任何一种情况下,指针都会将 "seek" 指向 .MYD 文件。
指针默认为 6 字节数字,允许大量行。它可以通过设置进行更改,以保存 space 或允许更大的行数。
对于您的特定查询,INDEX(col2, id)
是最优的,"covering"。对于 MyISAM,它优于 INDEX(col2)
,但对于 InnoDB,它们是等效的,因为 InnoDB 在每个二级索引中隐式地具有 PK。
查询必须扫描至少 5000+1000 行,至少在索引的 BTree 中。
请注意,InnoDB 的 PRIMARY KEY
与数据聚类,但 MyISAM 的 PRIMARY KEY
是一个单独的 BTree,就像其他二级索引一样。
你真的应该考虑转向 InnoDB;今天几乎没有理由使用 MyISAM。
我的问题:想象一个有数百万行的 table,比如
CREATE TABLE a {
id INT PRIMARY KEY,
column2..,
column3..,
many other columns..
..
INDEX (column2);
和这样的查询:
SELECT id FROM a WHERE column2 > 10000 LIMIT 1000 OFFSET 5000;
我的问题:mysql 只使用索引 "column2"(因此主键 id 隐式存储为其他索引中的引用),还是必须获取所有行才能获取还有选择用于输出的id?在那种情况下,使用声明为的键查询应该快得多:
INDEX column2(column2, id)
需要 column2
上的索引。您在索引中使用 id 的建议将阻止 table 扫描并且应该非常有效。
此外,假设 column2
是一个连续序列,这样做会更快:
SELECT id FROM a WHERE column2 > 15000 LIMIT 1000;
这是因为要使用偏移量,它只需扫描接下来的 5000 条记录(MySQL 没有意识到您实际上正在偏移 column2
)。
简答:否
长答案:
MyISAM与InnoDB不同,对每个索引的叶子节点中的数据有一个"pointer",包括那个PRIMARY KEY
.
所以,INDEX(col2)
本质上是 INDEX(col2, ptr)
。 INDEX(id)
的同上是 INDEX(id, ptr)
。
"pointer" 是 .MYD 文件中的字节偏移量(DYNAMIC
)或记录号(FIXED
)。在任何一种情况下,指针都会将 "seek" 指向 .MYD 文件。
指针默认为 6 字节数字,允许大量行。它可以通过设置进行更改,以保存 space 或允许更大的行数。
对于您的特定查询,INDEX(col2, id)
是最优的,"covering"。对于 MyISAM,它优于 INDEX(col2)
,但对于 InnoDB,它们是等效的,因为 InnoDB 在每个二级索引中隐式地具有 PK。
查询必须扫描至少 5000+1000 行,至少在索引的 BTree 中。
请注意,InnoDB 的 PRIMARY KEY
与数据聚类,但 MyISAM 的 PRIMARY KEY
是一个单独的 BTree,就像其他二级索引一样。
你真的应该考虑转向 InnoDB;今天几乎没有理由使用 MyISAM。