我Assets
在 InnoDB 引擎上有一个表,定义为:
CREATE TABLE Assets (
qid SMALLINT(5) NOT NULL,
sid BIGINT(20) NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (sid,qid),
KEY sid (sid)
);
我正在运行以下查询:
SELECT COUNT(*) FROM Assets WHERE sid>10000;
在我的机器上,这个查询大约需要 30 秒,表中有 200 万个条目。现在,如果我修改查询以使用索引,结果会有很大差异:
SELECT COUNT(*) FROM Assets USE INDEX(<index>) WHERE sid>10000;
NO INDEX
:无显式USE INDEX
,即第一次SELECT
查询:30 秒KEY sid (sid)
: 1.5 秒KEY cid (sid,qid)
: 1.5 秒PRIMARY
: 我用USE INDEX(PRIMARY)
内查询。: 30 秒
所以这些是我的问题:
我认为一个查询会自动使用主键作为它的索引,基于这个。
USE INDEX (cid)
然而和之间有一个主要区别NO INDEX
。有什么不同?另外,我如何明确地将主键作为索引?如果
NO INDEX
实际上不使用主键作为索引,那是USE INDEX(PRIMARY)
什么导致它具有与 相同的运行时间NO INDEX
?仅过滤的查询之间
USE INDEX(sid)
和之间是否存在差异(不仅仅是性能方面)?USE INDEX(cid)
sid
原谅这篇长文,但我想让它公开讨论。
好的,这是我到目前为止发现的:
首先,我被告知密钥设置应该是:PRIMARY KEY(qid,sid), KEY(sid)
或PRIMARY KEY(sid,qid), KEY(qid)
. 我真的不明白其中的区别。如果有人这样做,请告诉我。
其次,KEY sid
( sid
) 引用的索引页数远少于较大的键,因此它往往更快。至于使用 PRIMARY KEY 作为索引和正确的 KEY(即使它们使用相同的字段)之间的区别,我被告知它是这样的:
主键使用主键的字段索引整个表数据。这意味着 PRIMARY KEY 和数据存储在一起。因此,使用 PRIMARY KEY 的查询将不得不遍历整个表数据,即使是索引也会在大型不可缓存的表上陷入困境。
使用离散键,行数可能相同,但扫描的索引(由指示的字段组成)要小得多,它会命中较少数量的磁盘块,因此运行得更快。我假设这也是使用USE INDEX(cid)
和使用主键作为索引不同的原因,两者都具有相同的字段。