数据库表何时变得足够大以使索引有益?

Rob*_*vey 7 sql-server indexing performance

假设在SQL Server数据库中,如果我有一个包含两个int字段(比如多对多关系)的表,它参与另外两个表之间的连接,那么表的大小会变得足够大,其中性能优势两个int字段的索引是否克服了所述索引带来的开销?

不同版本的SQL Server之间的体系结构是否存在差异,从而大大改变了这个答案?

Qua*_*noi 11

对于涉及表行的一小部分的查询,索引总是有益的,有100行或1,000,000.

有关计划和性能详细信息的示例,请参阅我的博客中的此条目:

像这样的查询:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col = t1.col
Run Code Online (Sandbox Code Playgroud)

最有可能使用HASH JOIN.将构建较小表的哈希表,较大表中的行将用于探测哈希表.

为此,不需要索引.

但是,这个查询:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col = t1.col
WHERE   t1.othercol = @value
Run Code Online (Sandbox Code Playgroud)

将使用NESTED LOOPS:table1将使用索引on来搜索外部表()中table1.othercol的行,并使用索引来搜索内部表(table2)中的行table2.col.

如果您没有索引col1,HASH JOIN将使用一个需要扫描来自两个表的所有行和一些更多资源来构建哈希表.

索引对于这样的查询也很有用:

SELECT  t2.col
FROM    table1 t1
JOIN    table2 t2
ON      t2.col = t1.col
Run Code Online (Sandbox Code Playgroud)

在这种情况下,引擎根本不需要自己读取table2:您可以在索引中找到此查询所需的内容,该索引可以比表本身小得多,并且读取效率更高.

而且,当然,如果你需要你的数据分类和对两个索引table1.coltable2.col,则下面的查询:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col = t1.col
ORDER BY
        t2.col
Run Code Online (Sandbox Code Playgroud)

可能会使用MERGE JOIN方法,如果两个输入行集都已排序,并且其输出也已排序,这是超快的,这意味着它ORDER BY是免费的.

请注意,即使您没有索引,优化程序也可以选择Eager Spool您的小表,这意味着在查询期间构建临时索引并在查询完成后删除索引.

如果查询很小,它会非常快,但同样,索引也不会受到影响(对于SELECT我的意思).如果优化器不需要它,它就不会被使用.

但请注意,创建索引可能会影响DML性能,但这是另一个故事.