数据库 – 多个索引可以一起工作吗?

前端之家收集整理的这篇文章主要介绍了数据库 – 多个索引可以一起工作吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设我有一个包含两个字段“foo”和“bar”的数据库表.它们都不是唯一的,但是它们都是索引的.但是,它们不是一起索引,而是分别具有索引.

现在假设我执行一个查询,如SELECT * FROM soMetable WHERE foo =’hello’AND bar =’world’;我的桌子有很多行,其中foo是“hello”,少量的行是“世界”.

因此,数据库服务器在引擎盖下最有效的方法是使用bar索引来查找bar是“world”的所有字段,然后只返回foo为“hello”的那些行.这是O(n)其中n是bar是“world”的行数.

但是,我想象的是,这个过程可能会发生在相反的情况下,使用了fo索引并搜索结果.这将是O(m)其中m是foo是“hello”的行数.

那么Oracle智能足以在这里高效搜索?其他数据库呢?还是有一些我可以在我的查询中告诉我要按正确的顺序搜索?也许把WHERE子句中的bar =’world’放在第一位?

解决方法

Oracle几乎肯定会使用最有选择性的索引来驱动查询,您可以使用说明计划来检查.

此外,Oracle可以通过几种方式组合使用两个索引 – 它可以将btree索引转换为位图,并对其执行位图ANd操作,也可以对两个索引返回的rowid执行散列连接.

这里的一个重要考虑可能是被查询的值之间的任何相关性.如果foo =’hello’占表中的80%的值,并且bar =’world’占10%,那么Oracle将会估计该查询将返回0.8 * 0.1 = 8%的表行.但是这可能不正确 – 查询可能实际上返回rwos的10%甚至0%的行,具体取决于值的相关性.现在,根据整个表中这些行的分布情况,使用索引找到它们可能并不有效.您可能仍然需要访问(例如)70%或表块来检索所需的行(“for”集群因子“),在这种情况下,如果得到正确的估计,Oracle将执行完整的表扫描.

在11g你可以收集多列统计数据,以帮助我相信这种情况.在9i和10g中,您可以使用动态采样来获取要检索的行数的非常好的估计.

要得到执行计划,请执行以下操作:

explain plan for
SELECT *
FROM   soMetable
WHERE  foo='hello' AND bar='world'
/
select * from table(dbms_xplan.display)
/

对比:

explain plan for
SELECT /*+ dynamic_sampling(4) */
       *
FROM   soMetable
WHERE  foo='hello' AND bar='world'
/
select * from table(dbms_xplan.display)
/

猜你在找的MsSQL相关文章