假设在SQL Server数据库中,如果我有一个包含两个int字段(比如说多对多关系)的表,它参与其他两个表之间的连接,那么表的大小大小足够大两个int字段的索引的性能优势是否克服了所述索引带来的开销?
不同版本的SQL Server之间的体系结构是否存在差异,从根本上改变了这个答案?
答案 0 :(得分:11)
对于涉及表行的一小部分的查询,索引总是有益的,有100
行或1,000,000
。
有关计划和效果详情的示例,请参阅我的博客中的此条目:
这样的查询:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
很可能会使用HASH JOIN
。将构建较小表的哈希表,较大表中的行将用于探测哈希表。
为此,不需要索引。
但是,这个查询:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
WHERE t1.othercol = @value
将使用NESTED LOOPS
:将使用table1
上的索引和内部表(table1.othercol
中的行搜索外部表(table2
)中的行)将使用table2.col
上的索引进行搜索。
如果您在col1
上没有索引,则会使用HASH JOIN
,这需要扫描两个表中的所有行以及一些更多资源来构建哈希表。
索引对于这样的查询也很有用:
SELECT t2.col
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
,在这种情况下,引擎根本不需要读取table2
本身:您可以在索引中找到此查询所需的内容,该索引可以比表本身小得多,并且更高效读取。
当然,如果您需要对数据进行排序并在table1.col
和table2.col
上都有索引,那么以下查询:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
ORDER BY
t2.col
可能会使用MERGE JOIN
方法,如果两个输入行集都已排序,并且其输出也已排序,这超快,这意味着ORDER BY
是免费的。
请注意,即使您没有索引,优化程序也可以选择Eager Spool
您的小表,这意味着在查询期间构建临时索引并在查询完成后删除索引。
如果查询很小,它会非常快,但同样,索引也不会受到影响(我的意思是SELECT
个查询)。如果优化器不需要它,则不会使用它。
请注意,创建索引可能会影响DML
性能,但这是其他故事。
答案 1 :(得分:1)
索引几乎总是会增加查询的性能,代价是额外的内存和插入/删除的性能成本(因为它需要在该点维护索引)。在您的特定情况下,分析将是判断索引是否有益的唯一明确方法。
一般情况下,在创建索引时(除了额外的插入成本之外),您需要通过内存来提高速度。如果您相对于插入/删除的行数进行了许多查询(选择或更新),索引几乎总会提高您的性能。
答案 2 :(得分:1)
它取决于数据的选择性,如果您的数据不够有选择性,那么甚至可能不会使用索引,因为成本太高。如果表中只有2个值,并且这些值均匀分布,那么您将获得扫描而不是搜索
我仍然相信每个表都应该有一个主键,如果你有,那么你也有一个索引
答案 3 :(得分:1)
在索引的好处出现很久之后,插入的惩罚可以忽略不计。优化器非常智能,无论如何都要忽略索引,直到点击为止。所以只需从表开始索引表。
答案 4 :(得分:1)
要考虑的另一件事是编码性能的概念 - 有时候有一个索引可以简化思考如何管理不同数据之间关系的心理开销。有时它会使它复杂化......
答案 5 :(得分:1)
无论大小如何,在执行查找时使用索引始终具有性能优势。
关于开销,问题变成:你的意思是什么开销,以及你如何将它与查找的价值联系起来?毕竟,这两者是不同的价值观。
索引有两种形式的开销:空间(通常可以忽略不计,具体取决于索引的结构),以及对insert的重新索引(服务器必须在每次插入后重新计算索引)。
正如我所提到的,太空问题可能并不是什么大问题。但重新索引是。幸运的是,在这种形式的开销成为问题之前,你需要进行大量的近连续插入。
所以底线:你几乎总是更好地拥有一个索引。从该位置开始,等待重新索引成为瓶颈。然后你可以看看替代品。
答案 6 :(得分:1)
一个非常有用的链接: “临界点查询答案” http://www.sqlskills.com/BLOGS/KIMBERLY/post/The-Tipping-Point-Query-Answers.aspx
答案 7 :(得分:1)
最好的事情是让服务器自己搞清楚。你可以在有意义的列中创建索引(我确定有完整的章节,如果没有关于如何以最佳方式执行此操作的书籍),并让SQL服务器弄清楚何时/如何使用索引。
在许多情况下,在优化时,您需要阅读特定DBMS的文档,以了解它如何使用索引,并将其与您正在优化的应用程序使用的查询相关联。然后你可以微调索引的使用。
答案 8 :(得分:0)
我相信一旦你开始在那些int字段上加入你的表就够了。如果表足够小以至于它不会从索引中受益,那么开销就不会太大而你想要选择退出。
当我考虑索引引起的开销时,我通常会考虑表索引的更改频率 - 通过插入,删除和更新索引列。