我不擅长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问题,但我要求更通用的东西,可能更简单。
任何帮助表示赞赏!
答案 0 :(得分:17)
您肯定希望attributeID
和attributes
表上的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”中使用它。因此,尝试使用“在哪里”条件