当前位置:  开发笔记 > 运维 > 正文

多个索引可以一起工作吗?

如何解决《多个索引可以一起工作吗?》经验,为你挑选了1个好方法。

假设我有一个包含两个字段的数据库表,"foo"和"bar".它们都不是唯一的,但每个都被编入索引.但是,它们每个都有一个单独的索引,而不是被索引在一起.

现在假设我执行一个查询,例如SELECT * FROM sometable WHERE foo='hello' AND bar='world'; My table,foo为'hello'的行数很多,而bar为'world'的行数很少.

因此,数据库服务器最有效的方法是使用bar索引查找bar为'world'的所有字段,然后仅返回foo为'hello'的那些行.这是O(n)n是bar为'world'的行数.

但是,我想这个过程可能会反过来,使用fo索引并搜索结果.这就是O(m)m是foo为'hello'的行数.

那么Oracle足够聪明,可以在这里高效搜索吗?其他数据库怎么样?或者有什么方法可以在我的查询中告诉它以正确的顺序搜索?也许bar='world'WHERE条款中排在第一位?



1> David Aldrid..:

Oracle几乎肯定会使用最具选择性的索引来驱动查询,您可以使用解释计划进行检查.

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

这里一个重要的考虑因素可能是被查询的值之间的任何相关性.如果foo ='hello'占表中值的80%且bar ='world'占10%,那么Oracle将估计查询将返回0.8*0.1 = 8%的表行.然而,这可能不正确 - 查询实际上可能返回10%的rwos甚至0%的行,具体取决于值的相关性.现在,根据整个表中这些行的分布,使用索引来查找它们可能效率不高.您可能仍需要访问(比方说)70%或表格块来检索所需的行(谷歌搜索"聚类因子"),在这种情况下,如果估计结果正确,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)
/

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有