2010-02-05 88 views
4

我正在使用SQL 2000,并且在包含大约3000万行的表上运行简单的select语句。选择查询如下所示:优化选择查询

select col1, col2, col3 from Table1 where [email protected] and [email protected] and [email protected] 

表中有一个聚集索引(即主键),但没有用作where条件。上面提到的所有标准都没有索引。

如何优化此查询?

如果我在where子句中为每列添加索引,那会有什么区别吗?

如果我在where子句中有10个列,那么这10个列中的所有列都有索引吗?

编辑:这可能是最常见的面试问题之一:)

回答

5

是的,它会产生巨大的差异。

您应该添加一个包含三个字段的索引,而不是为每个字段添加一个索引。 (当然这在实践中的使用取决于字段的独特性以及您将在桌面上使用的其他查询)。

请注意,添加索引时,插入或删除时也会产生很小的负面影响记录到表中或更新记录的索引字段。

+0

指数功效神奇!谢谢....但只是好奇,有没有其他方法可以用来更快地做出这样的查询? – Bhaskar 2010-02-05 12:44:55

+0

@Bhaskar:是的,你可以走得更远。分析执行计划,看看最需要的是什么。最有效的索引取决于表中包含的数据以及它的变化量。如果表中有许多插入/更新/删除操作,则应检查索引的碎片并在索引趋向于碎片时指定填充因子。 – Guffa 2010-02-05 13:00:57

2

如果我添加索引中 每列的where子句中,这会让任何 区别?

是的,添加索引会产生巨大的性能差异。这是以索引占用大量磁盘空间为代价的,并且对INSERT和UPDATE命令的影响非常小。

如果我有where子句中10列, 都应该在这10列在他们 指数?

情况并非总是如此。如果我们以您提供的SQL查询为例,并且仅在col4上创建索引,那么select * from Table1 where [email protected]可能只返回几条记录。在这种情况下,由于数据库引擎只需扫描返回的那几条记录,就不会在col5和col6上获得太多索引。

因此,正如您所看到的,这取决于您正在存储的数据类型。另外,对于任何基数较低的列(即只有少量唯一值的列),索引也可能没有多大用处。

2

来自标准的哪一列最具选择性?在该列上创建索引最会影响性能。 如果您将另一列添加到相同的索引或不是,取决于选择性。您需要检查查询计划以找出该问题:)

4

如何优化此查询?

您可以覆盖索引:

CREATE INDEX ix_table1_456__123 ON table1 (col4, col5, col6) INCLUDE (col1, col2, col3) 

,查询甚至不会做一个表查找。

如果我在where子句中为每列添加索引,那会有什么区别吗?

与没有索引相比,这将最有可能改善查询,但创建包含覆盖的组合索引最可能会更好。但是,如果每个列的基数都很高(即它是UNIQUE或接近它),那么与组合索引相比,创建单个索引甚至可以提高查询的质量。

如果某些列的大小很大(例如VARCHAR(400)),而另一个小列的基数较高,则尤其如此。

如果我在where子句中有10列,那么这10列中的所有列都有索引吗?

如果你有10列,还有的,正如我上面所说,并增加了密钥大小之间的权衡(这会降低性能),增加选择性。

如果比方说第一个3列是唯一的或几乎唯一的,那么添加附加列不会增加选择性,但会增加密钥大小。

该索引将会变得更大,这将需要额外的时间来搜索它。

如果3列提供足够高的选择性,则不应在所有10列上创建索引,因为遍历较大的索引将比读取一些额外的键更昂贵。

您可能需要阅读这篇文章在我的博客:

+0

索引像魔术一样工作!谢谢....但只是好奇,有没有其他方法可以用来更快地做出这样的查询? – Bhaskar 2010-02-05 12:45:29