4

这是我的桌子的样子:

CREATE TABLE pics(
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT,
  page INTEGER,
  w INTEGER,
  h INTEGER,
  FOREIGN KEY(page) REFERENCES pages(id) ON DELETE CASCADE,
  UNIQUE(name, page)
);

CREATE INDEX "myidx" ON "pics"("page");  # is this needed?

所以UNIQUE(name, page)应该创建一个索引。但是这个索引是否足以进行page仅涉及该字段的快速查询?就像选择一组“图片”一样WHERE page = ?。还是JOIN pages.id ON pics.page?或者我应该为页面字段创建另一个索引(myidx)吗?

4

3 回答 3

6

如前所述,您将需要其他myidx索引,因为您的UNIQUE索引name首先指定。换句话说,它可以用于查询:

  1. name
  2. namepage
  3. 不是一个人page

您的另一个选择是重新排序UNIQUE索引并将page列放在首位。然后它可以page仅用于查询,但将与name仅查询不兼容。

于 2013-08-06T15:33:04.017 回答
3

将复合索引视为电话簿。电话簿姓氏排序,然后是名字。如果您的名字是Bob Smith,您可以快速找到S部分,然后是Sm,然后是所有Smith的,最后是Bob。这很快,因为您在索引中有两个键。由于这本书是按姓氏排列的,因此找到所有Smith条目也同样简单。

现在想象一下,试图在整个电话簿中找到所有Bob的人。更难,对吧?

这也类似于磁盘上的索引的组织方式。在按顺序排序的列表中查找具有特定页面(name, page)列的所有行基本上会导致对所有行的顺序扫描,逐一查找具有该页面的任何内容。

有关索引如何工作的更多信息,我建议阅读使用索引,卢克

于 2013-08-06T15:45:33.410 回答
2

您必须分析将使用此表的查询并确定查询将使用哪些字段对结果进行排序。您应该索引用于排序最多的字段。

于 2013-08-06T15:33:34.133 回答