主键是否隐式存储在mysql myisam引擎的其他键中?

主键是否隐式存储在mysql myisam引擎的其他键中?,mysql,indexing,myisam,Mysql,Indexing,Myisam,我的问题是:想象一个有数百万行的表,比如 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隐式存储为其他索引中的引用),还是

我的问题是:想象一个有数百万行的表,比如

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)

需要在
列2
上建立索引。您在索引中使用id的建议将阻止表扫描,并且应该非常有效

此外,如果
column2
是一个连续序列,则执行此操作的速度更快:

SELECT id FROM a WHERE column2 > 15000 LIMIT 1000;
这是因为使用偏移量只需扫描接下来的5000条记录(MySQL没有意识到您实际上正在偏移
column2
)。

简短回答:否

长答覆:

与InnoDB不同,MyISAM有一个指向每个索引的叶节点中的数据的“指针”,包括
主键

所以,
INDEX(col2)
本质上就是
INDEX(col2,ptr)
。对于
索引(id)
索引(id,ptr)
,同上

“指针”是指向.MYD文件的字节偏移量(对于
动态
)或记录编号(对于
固定
)。无论哪种情况,指针都会指向.MYD文件中的“seek”

指针默认为6字节的数字,允许有大量的行。它可以通过设置进行更改,以节省空间或允许更大的行数

对于您的特定查询,
索引(col2,id)
是最佳的且“覆盖”。对于MyISAM,它比
INDEX(col2)
更好,但是对于InnoDB,它们是等效的,因为InnoDB隐式地在每个二级索引中都有PK

查询必须至少扫描5000+1000行,至少在索引的BTree中

请注意,InnoDB的
主键
与数据聚集在一起,但MyISAM的
主键
与其他二级索引一样,是一个单独的BTree


你真的应该考虑搬到NiNDB;今天几乎没有理由使用MyISAM。

谢谢,这回答了我的问题(防止表扫描,在我的情况下,这似乎非常慢)。你建议省略抵消对我不起作用,因为第2列中的数据不是一个连续的序列。啊,对那部分来说太糟糕了。您可以从偏移范围中记录最后找到的值,以便当用户要求下一个偏移时,您可以使用上一个偏移的最大值。(因此,偏移量仍然存在,但在下一页的每一页上,都使用先前检索到的最大值(第2列))