我在表T的列A,B,C,D上有一个索引

我有一个查询,它在WHERE子句中使用A,B,C从T中提取。

是否需要使用索引,还是需要一个仅包含A,B,C的单独索引?

有帮助吗?

解决方案

David B是正确的,您应该检查执行计划以验证索引是否正在使用。

是否需要使用索引或是否需要一个仅包含A,B,C的单独索引?

要回答问题的最后一部分,我认为这是核心基础主题(而不是直接解决方案),几乎从来没有理由索引索引列的子集。如果您的索引是(A,B,C,D),那么针对(A,B,C)的WHERE很可能会导致索引 seek ,这是理想的情况 - 索引包括引擎需要直接进入结果集的所有信息。我相信这对数字类型和字符串类型中的相等测试都适用,尽管它可以与LIKE'%'分解。另一方面,如果你的WHERE只引用了D,你很可能最终得到一个索引 scan ,这意味着SQL引擎必须扫描A,B和C,然后在决定是否将行添加到结果集之前检查D是否符合您的条件。在一个特别大的表上,当我发现自己不得不对列“D”进行大量查询时,我只为D添加了一个额外的索引,并且看到了大约90%的性能提升。

编辑:我还应该建议在SQL Management Studio中使用数据库引擎优化顾问。它会告诉您表格是否未针对要运行的查询进行理想索引。

其他提示

取决于!

WHERE A like '%x%'
  and B = 1
  and C = 1
//
WHERE A = 1
  OR B = 1
  OR C = 1
//
WHERE DateAdd(dd, 1, A) = '2008-01-01'
  AND B = 1
  AND C = 1

这些不依赖于索引,因为索引没用。

点击“显示估算的执行计划”确认潜在的指数用途。

在Oracle数据库中,这称为综合指数 (12g文档,但对早期版本有效)

  

复合索引可以加速检索SELECT语句的数据,其中WHERE子句引用复合索引中列的所有前导部分。因此,定义中使用的列的顺序很重要。通常,最常访问的列首先出现。

所以在你的情况下,是的。该指数将/可以使用。这可以通过使用解释计划来验证。

如果MS SQLSERVER不同(我怀疑它可能),你需要一个新答案。

修改 还应该提到它只会考虑使用的索引..这并不一定意味着它会使用它。

<强> EDIT2: Oracle 11g及更高版本现在有一个选项,允许它跳过索引中的列。所以对A,B和D的查询可能仍然使用索引

将使用索引,是的。关于哪些索引会产生更优化的查询计划是相当明智的,它应该没有问题。

就像这种事情一样,不要相信我的话 - 对它进行基准测试。创建一个表,用代表性数据填充,查询,索引并再次查询。

索引包含未在查询中使用的列的事实不会阻止它被使用。

这并不是说肯定使用,可能会因为其他原因而被忽略(可能是因为一个或多个其他索引更有用)。

与往常一样,对估计的执行计划采取措施,看看可能会发生什么。

从简单的等于查找开始(WHERE A = 1,B ='Red'和C = 287)是的,索引(最有可能)将被使用。该索引将首先用于帮助优化器“猜测”。与选择匹配的行数,然后是实际访问这些行的行数。

回应David B关于“喜欢”的评论谓词,SQLServer仍然可以使用索引,这取决于你选择的是什么。例如,如果您选择计数(*),则SQLServer可能会扫描索引并计算与where子句匹配的命中数,因为索引较小并且需要较少的IO才能扫描。即使您从基表中选择一些列,也可能决定这样做,具体取决于SQLServer对索引的选择程度。

这是另一个“它取决于”回答......这也取决于你的桌子有多大......

我同意其他提及检查执行计划以验证您的索引是否被使用的人。

以下是一些关于阅读您认为有用的执行计划的文章:

http://www.sqlservercentral.com/articles/Administering/executionplans/ 1345 / http://www.codeproject.com/KB/database/ SQL调谐教程-1.aspx

我还推荐一篇关于搜索与扫描的文章: http://blogs.msdn.com/craigfr/archive/ 2006/6月26日/ 647852.aspx

Craig Freedman的博客上有一篇很好的文章记录,这是你应该发现的另一个有用的文章。本文是关于SQL Server用于确定使用哪个索引的一些因素...

http://blogs.msdn.com/craigfr /archive/2006/07/13/664902.aspx

小心! 杰夫

一般来说是的,所有现代数据库都足够聪明地做到这一点。例如,有一些例外情况,如果表中的统计数据显示其中的数据量足够小,使得完整的表读取将更有效,那么索引将被打折,但通常,您可以依赖它在适当的地方。

因此,您可以在设计索引时利用这一点。比方说,我有一个表,其中包含A,B,C作为键值,列Y和Z包含我知道将经常通过语句检索的数据

SELECT Y FROM table WHERE A = alpha and B = beta and C = gamma 

SELECT Z FROM table WHERE A = alpha and B = beta and C = gamma 

我通常会在A,B,C,X,Z上创建一个索引 - 假设X和Z是一个相当小的字段。这样做的原因是我知道上面语句中的访问路径将使用索引,而因为我要检索的数据已经在索引读取然后没有单独读取数据块需要检索表数据本身。在某些情况下,此策略可以显着加快数据检索速度。当然,您需要在更新成本和磁盘空间中支付费用,因此在应用数据库之前需要了解数据库正在执行的操作,但是在大多数数据库中读取的数据显着超出了写入数量,因此通常值得考虑。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top