如何加快简单加入

时间:2009-05-27 17:06:27

标签: sql-server performance join

我不擅长SQL。

我正在寻找一种方法来加速这样的简单连接:

SELECT
    E.expressionID,
    A.attributeName,
    A.attributeValue
FROM 
    attributes A
JOIN
    expressions E
ON 
    E.attributeId = A.attributeId

我这样做了几十万次,随着桌子越来越大,它越来越多。

我正在考虑索引 - 如果我要加快对单个表的选择,我可能会在表达式上为表达式表放置非聚簇索引,为属性表放置另一个(attributeName,attributeValue) - 但我不这样做知道这如何适用于加入。

编辑:表达式表上已经有了expressionId(PK),attributeId(PK,FK)的聚簇索引,属性表上的attributeId(PK)上有另一个聚簇索引

我见过this问题,但我要求更通用的东西,可能更简单。

任何帮助表示赞赏!

7 个答案:

答案 0 :(得分:17)

您肯定希望attributeIDattributes表上的expressions上都有索引。如果你现在没有这些索引,我想你会看到一个很大的加速。

答案 1 :(得分:6)

事实上,因为返回的列很少,我会考虑这个查询的覆盖索引

即。包含查询中所有字段的索引。

答案 2 :(得分:3)

您需要关注的一些事情是索引,查询计划和统计信息。

在attributeId上放置索引。或者,确保索引存在,其中attributeId是键中的第一列(如果SQL Server不是第一列,它仍然可以使用索引,但它不是那么快)。

在查询分析器中突出显示查询,然后按^ L查看计划。您可以看到表如何连接在一起。 几乎总是,使用索引总比没有好(有一些边缘情况,如果表足够小,索引可能会减慢你的速度 - 但是现在,请注意99%的时间索引很好)。

注意表的连接顺序。 SQL Server维护有关表大小的统计信息,并将确定哪个更适合首先加入。对内部SQL Server程序进行一些调查以更新统计信息 - 它已经太长了,所以我没有那么方便的信息。

这应该让你开始。实际上,整个章节可以写成数据库如何优化甚至这么简单的查询。

答案 3 :(得分:2)

我敢打赌你的问题是插入到临时表中的大量行数。有没有什么办法可以在WHERE数据库的每一行之前添加SELECT子句?

答案 4 :(得分:1)

另一件事是添加一些像这样的索引:

attributes.{attributeId, attributeName, attributeValue}
expressions.{attributeId, expressionID}

这很hacky!但如果它是最后的手段,那就很有用。

这样做是为了创建一个可以被索引“完全回答”的查询计划。通常,索引实际上会在上面的查询中导致双I / O:一个用于命中索引(即探测到表),另一个用于获取索引引用的实际行(用于拉取attributeName等)。 / p>

如果“属性”或“表达式”是一个宽表,这将特别有用。也就是说,从中获取行的代价很高。

最后,加快查询速度的最佳方法是添加一个WHERE子句!

答案 5 :(得分:1)

如果我正确理解你的架构,你会说你的桌子看起来像这样:

Expressions: PK - ExpressionID, AttributeID
Attributes:  PK - AttributeID

假设每个PK都是聚簇索引,这仍然意味着Expressions表上需要进行索引扫描。您可能需要考虑在 Expressions 表上创建索引,例如: AttributeID,ExpressionID 。这有助于停止当前发生的索引扫描。

答案 6 :(得分:0)

提示

如果您想使用join加快查询速度:

对于“内部联接/联接”,
     不要使用where条件,而应使用“ ON”条件。
         例如:

         select id,name from table1 a  
       join table2 b on a.name=b.name
       where id='123'

     Try,

        select id,name from table1 a  
       join table2 b on a.name=b.name and a.id='123'

对于“左/右连接”,
                    不要在“ ON”条件下使用,因为如果使用左/右联接,它将获得任何一张表的所有行。因此,请勿在“ On”中使用它。因此,尝试使用“在哪里”条件