SQL跨表索引的方法?

时间:2015-08-13 19:13:50

标签: mysql sql indexing

有没有办法在表之间创建多列索引?

例如,如果我有以下表格:

Foo (Table Name)
  FooID (PK)
  BarID (FK)
  FooName

Bar (Table Name)
  BarID (PK)
  BarName

我可以做一个

SELECT * 
FROM Foo 
LEFT JOIN Bar ON Foo.BarID = Bar.BarID
WHERE 
  FooName < "Bob"
  AND BarName > "Smith";

在这种情况下,我想要一个针对Foo.FooName then Bar.BarName的多列索引。

我做了一些谷歌搜索,但无法找到任何东西,也许我没有使用正确的条款......我的问题可能取决于sql引擎,在这种情况下我特别感兴趣的是MySQL,但是欣赏任何其他引擎的信息。

使用外键在Foo上执行多列索引没有帮助,因为其名称的基础值是我想要的速度。

3 个答案:

答案 0 :(得分:1)

闻起来过度正常化&#34;。可能值得将这两个字段移到同一个表中吗?

Akiban是一个可以进行交叉表JOINs等的引擎,但它不再存在。

&#34;物化视图&#34;在MySQL中不存在(除非你自己实现它们)。

答案 1 :(得分:1)

多年后来到我自己的帖子,并认为我可以添加一些细节,以防其他人有类似的问题。正如Mark B指出的那样,每个索引都是按表格进行的,但是我们可以设置一些能够提高效率的指标,见下文。

这里有几个不同的东西,所以可以使用索引来帮助我们完成我们需要的东西。我们需要一个索引来帮助过滤主表,然后是一个适用于第二个表的连接和过滤的索引。为了帮助实现这一目标,我们可以创建以下两个索引:

CREATE INDEX idx_fooname ON Foo (FooName);
CREATE INDEX idx_barid_barname ON Bar (BarID, BarName);

一旦这些索引到位,就可以使用如下查询:

SELECT * 
FROM Foo USE INDEX(idx_fooname)
LEFT JOIN Bar USE INDEX (idx_barid_barname) ON Foo.BarID = Bar.BarID
WHERE 
  FooName < "Bob"
  AND BarName > "Smith";

答案 2 :(得分:0)

正如xQbert所提到的,你可以使用物化视图(如果你使用Microsft SQL Server,你可以使用索引视图)。

但首先您必须将LEFT JOIN更改为INNER JOIN(因为实体化/索引视图无法处理外部联接。左侧连接在您的查询中似乎没有意义因为WHERE ... BarName > "Smith"

如果您使用SQL Server,该链接可能对您有所帮助:https://www.simple-talk.com/sql/learn-sql-server/sql-server-indexed-views-the-basics/

创建实体化/索引视图后,您可以直接查询视图(我不确定查询优化器是否会自动使用它)。 请注意,当您INSERTDELETEUPDATE进入已使用的表时,实体化/索引视图会降低您的性能(每个索引也将执行此操作)。最好的想法只是将实际需要的字段添加到物化/索引视图中。