1

我有一些类似于以下的 SQL,它连接四个表,然后按第一个的“状态”列对结果进行排序:

SELECT * 
 FROM a, b, c, d 
 WHERE b.aid=a.id AND c.id=a.cid AND a.did=d.id AND a.did='XXX'
 ORDER BY a.status

有用。但是,它很慢。我发现这是因为 ORDER BY 子句和表“a”上没有任何索引。

所有四个表都在“id”列上设置了 PRIMARY KEY。

所以,我知道我需要向包含“状态”列的表 a 添加一个索引,但它还需要包含什么?“bid”、“cid”和“did”也应该在里面吗?

我试图从一般的 SQL 意义上问这个问题,但如果它很重要,那么目标是与 Gears 一起使用的 SQLite。

提前致谢,

杰克(菜鸟)

4

3 回答 3

4

我会说它很慢,因为引擎正在整个地方进行扫描而不是寻找。你的意思是 SELECT a.* 代替吗?那也会更快,这里的 SELECT * 相当于 a.*, b.*, c.*, d.*。

如果您在这些列中的每一列上放置一个单独的索引,您可能会得到更好的结果:

  • a.did(因此 a.did = 'XXX' 是查找而不是扫描,也有助于 a.did = d.id)
  • a.cid(对于 a.cid = c.id)
  • b.aid(对于 a.id = b.aid)

您可以尝试使用 ASCENDING 顺序将 Status 添加到第一个和第二个索引,以获得额外的性能 - 它不会受到伤害。

于 2009-06-18T08:49:48.930 回答
0

我很好奇你是如何发现问题是“ORDER BY 子句和表“a”上缺少任何索引。我觉得这有点可疑,因为表 a 上有一个索引,主键上,你后来说。

查看查询的性质以及我对数据性质的猜测,我认为与它使用的表的大小相比,这个查询通常会产生相对较少的结果,因此 ORDER BY 会非常便宜的。当然,这只是一个猜测。

索引是否有帮助取决于表中的数据。查询优化器在执行查询时将使用哪些索引取决于许多不同的因素,其中一个重要因素是查找产生的预期结果数量。

有很大帮助的一件事是,如果您发布 EXPLAINing 您的查询的输出。

于 2009-06-18T08:30:40.933 回答
0

你试过加入吗?

select * from a inner join b on a.id = b.aid inner join c on a.cid = c.id inner join d on a.did=d.id where a.did='XXX' ORDER BY a.status

连接(左、里奇、内、外)的正确使用取决于表的结构

希望这可以帮助

于 2009-06-18T08:50:24.857 回答