如何在select语句中使用索引?

129
假设我在员工表中创建了一个索引(idx_name)在表的emp_name列上。
在select语句中是否需要显式指定索引名称,或者它会自动用于加速查询?
如果需要在select子句中指定它,使用索引的语法是什么?
8个回答

126

如果你想测试索引是否有效,以下是语法:

SELECT *
FROM Table WITH(INDEX(Index_Name))

使用 WITH 语句可以强制使用索引。


107
这篇文章未回答问题。简而言之,答案是:您无需在查询中指定索引。它会自动使用(或不使用)。但是您可以强制执行它。关于何时以及为什么要这样做的更多详细信息,请参见下面的其他帖子。 - Rast
4
本文回答了最相关的部分,“在select查询中如何使用索引语法?”。它并没有明确说是否需要使用索引。在我的使用情况下,存在一个索引,但由于某些原因它没有被使用。在表名后面添加WITH(INDEX(..))可以解决我的问题! - xorcus

42

好问题,

通常情况下,数据库引擎应该根据它建立的查询执行计划自动选择要使用的索引。然而,在一些非常罕见的情况下,您可能需要强制DB使用特定的索引。

要回答您具体的问题,您需要指明您正在使用的DB。

对于MySQL,您需要阅读索引提示语法文档以了解如何实现此操作。


36

如何在 select 语句中使用索引?
方法如下:

   SELECT * FROM table1 USE INDEX (col1_index,col2_index)
    WHERE col1=1 AND col2=2 AND col3=3;


SELECT * FROM table1 IGNORE INDEX (col3_index)
WHERE col1=1 AND col2=2 AND col3=3;


SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX (i2) USE INDEX (i2);

还有更多的方法可以查看,请参考这里

我需要明确指定吗?

  • 不需要明确指定。
  • 数据库引擎应该会根据查询执行计划自动选择要使用的索引,这是根据@Tudor Constantin的回答所建立的。
  • 优化器将判断使用索引是否能提高查询速度,如果是,它将使用该索引,这是根据@niktrl的回答。

14

一般情况下,如果使用索引的成本比仅扫描整个表的成本更低,然后可能需要执行进一步的书签查找,则将使用索引。

如果您的查询形式为:

SELECT Name from Table where Name = 'Boris'

如果在1000行数据中仅有1行名称为Boris,那么它几乎肯定会被使用。但如果每个人的名字都是Boris,那么很可能会采用表扫描,因为索引不太可能成为访问数据更有效的策略。

如果这是一个宽表(列很多),并且您执行以下操作:

SELECT * from Table where Name = 'Boris'

如果从表中检索其他列需要的时间比仅查找名称要长,或者如果在任何情况下都可能检索大量行,则它仍然可以选择执行表扫描。


9

优化器会判断使用索引是否可以使您的查询运行更快,如果是,则会使用索引。

根据您使用的关系数据库管理系统,您可以强制使用索引,但除非您知道自己在做什么,否则不建议这样做。

通常情况下,您应该对在表联接和where语句中使用的列建立索引。


7
通常情况下,当您在表上创建索引时,数据库将自动在搜索该表中的数据时使用该索引。您不需要做任何事情。
然而,在MSSQL中,您可以指定一个“索引提示”,它可以指定使用特定的索引来执行此查询。有关此更多信息,请单击这里
“索引提示”似乎也适用于MySQL。感谢Tudor Constantine。

6

通过在条件中使用应用索引的列,它将自动包含在内。您不必使用它,但是当使用它时,查询速度会更快。

SELECT * FROM TABLE WHERE attribute = 'value'

会使用适当的索引。


4
索引提示仅适用于Microsoft Dynamics数据库服务器。对于传统的SQL Server,您在“Where”子句中定义的过滤器应该能够说服引擎使用任何相关索引......只要引擎的执行计划能够有效地确定如何读取信息(无论是完全表扫描还是索引扫描) - 它必须在执行语句之前将两者进行比较,作为内置性能优化器的一部分。
但是,您可以通过使用类似以下内容来强制进行优化器扫描:
    Select  *
    From    [yourtable] With (Index(0))
    Where   ...

或者通过类似以下方式查找特定索引位置

    Select  *
    From    [yourtable] With (Index(1))
    Where   ...

选择权在你手中。在对象面板中查看表的索引属性,以了解您想要使用的索引。它应该与您的过滤器匹配。
为了获得最佳结果,请首先列出返回最少结果的过滤器。 我不知道我说的是否正确,但似乎查询过滤器是顺序的;如果您按照正确的顺序进行操作,则优化器不应该通过比较所有组合来完成此操作,或者至少不应该从更昂贵的查询开始比较。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接