对指数的澄清

时间:2017-12-09 16:01:35

标签: sql oracle12c

为了说明我的问题,我将使用以下示例:

CREATE INDEX supplier_idx
  ON supplier (supplier_name);

如果在SELECT子句中指定了supplier_name列,是否只会加速对此表的搜索?如果我们选择supplier_name列以及SELECT子句中的其他列,该怎么办?如果在WHERE子句中使用此列,即使它不在SELECT子句中,也会加快搜索速度吗?

同样的规则也适用于以下索引:

CREATE INDEX supplier_idx
  ON supplier (supplier_name, city);

1 个答案:

答案 0 :(得分:1)

索引可能很复杂,因此完整的解释需要大量的写作。互联网上有很多资源。 (有用的链接here到Oracle索引)

但是,我可以简单地回答你的问题。

CREATE INDEX supplier_idx
  ON supplier (supplier_name);

这意味着使用col supplier_name并在WHERE子句中使用col supplier_name的任何连接(和类似)都将受益于索引。

例如

SELECT * FROM SomeTable
WHERE supplier_name = 'Smith'

但是只使用supplier_name子句中的SELECT列不会从索引中受益(除非你增加了SELECT子句的复杂性,我将介​​绍......) 。例如,这将 supplier_name

上的索引中受益
SELECT
supplier_name
FROM SomeTable WHERE ID = 1

但是,如果您在SELECT语句中添加了一些复杂性,那么您的索引确实可以加快它...例如:

SELECT
supplier_name   -- no index benefit
,(SELECT TOP 1 somedata FROM Table2 WHERE supplier_name = Table2.name) AS SomeValue
-- the line above uses the index as supplier_name is used in WHERE
, CASE WHEN supplier_name = 'Best Supplier'
  THEN 'Best'
  ELSE 'Worst'
  END AS FindBestSupplier
--  Also the CASE statement will use the index on supplier_name
FROM SomeTable WHERE ID = 1

(上面的'复杂性'仍然基本上表明,如果supplier_nameCASE中使用了字段WHERE'作为JOINS和聚合,那么INDEX是非常有益的......上面这个例子是包含在一个SELECT语句中的许多子句的组合)

但是你的综合指数

CREATE INDEX supplier_idx
  ON supplier (supplier_name, city);

在特定和重要的情况下会有所帮助(例如:city子句中的SELECTsupplier_name子句中使用的WHERE),示例

SELECT
city
FROM SomeTable WHERE supplier_name = 'Smith'

原因是citysupplier_name索引值一起存储,因此当索引找到supplier_name值时,它会立即获得city值的副本(存储在索引中)并且不需要命中数据库文件来查找更多数据。 (如果city不在索引中,则必须访问数据库以提取city值,因为它通常与SELECT语句中所需的大多数数据一样)

连接也将受益于索引,例如:

SELECT
* FROM SomeTable T1
LEFT JOIN AnotherTable T2 
ON T1.supplier_name = T2.supplier_name_2
AND T1.city = T2.city_2

总而言之,如果您在任何比较表达式中使用该字段,例如WHERE子句或JOIN,或GROUP BY子句(以及聚合SUM, MIN, MAX等)...那么一个索引对于超过几千行的表非常有用...... (通常只有在表中至少有10,000行时才会有很大的不同,但这可能因您的复杂程度而异)

SQL Server(例如)总是创建它需要的任何缺失索引(然后丢弃它们)。所以如果你不手动创建正确的索引 - 系统会因为它而变慢每次需要时动态创建缺失的索引。 (SQL Server将向您显示它认为您对某个查询所需的索引的提示)

索引可以减慢UPDATES或INSERTS,因此必须使用它们一点点智慧和平衡...(有时在执行一批UPDATE之前删除索引,然后再次重新创建索引,虽然这有点极端)