Sql Oracle:利用使用两个索引

Sql Oracle:利用使用两个索引,sql,oracle,indexing,Sql,Oracle,Indexing,正如您所见,Oracle可以利用两个索引来解决整个查询,而无需通过rowid访问表 SELECT 'Scarti letture GAS' tipo, campo47 pdf, COUNT (1) n FROM out.CONSUMI_GEE_LC_T500_00 v WHERE stato = 'SC' AND stato is not null AND campo47 is not null GROUP BY 'Scarti letture GAS', campo47;

正如您所见,Oracle可以利用两个索引来解决整个查询,而无需通过rowid访问表

SELECT  'Scarti letture GAS' tipo, campo47 pdf, COUNT (1) n
  FROM out.CONSUMI_GEE_LC_T500_00 v
  WHERE stato = 'SC'
  AND stato is not null
  AND campo47 is not null
  GROUP BY 'Scarti letture GAS', campo47;
我做了一个测试,将field campo47添加到STATO索引中。性能从1'49''提升到0,6秒

stato上的索引不是选择性的。campo47(它的意思是field47)上的索引确实是有选择性的


你说CAMPO47是高度选择性的。但您只是在不为NULL的情况下进行筛选。因此,不管它有多少不同的值,优化器都不会将其用作入口点

它有多大的选择性?从解释计划中的基数可以看出,选择on STATO='SC'会在表中找到12856行。其中12702行的CAMPO47带有一个值,因此空性测试只过滤掉154行。如果优化器选择了CAMPO47上的索引,那么会返回多少行?可能更多

优化器只能使用一个堆索引来访问表上的行。(位图索引应用星形变换时的机制不同)。因此,如果您认为额外的表访问是一个无法忍受的负担,那么您有一个选择:复合索引。如果STATO确实是非选择性的(相对较少的行),那么用on(STATO,CAMPO47)替换现有索引可能是安全的


有一个老把戏可以迫使数据库使用索引来访问is NOT NULL操作,那就是使用一个操作数,该操作数只能在列包含值的情况下为true。例如,对于字符串列(我假设一个名为CAMPO47的东西就是一个字符串):


将匹配包含一个或多个ascii字符的任何列。不确定这是否会导致你所描述的“双指数”优化,但值得一试。(我会自己测试,但我现在没有访问Oracle数据库的权限,当我试图查看解释计划时,SQL Fiddle被抛出)

如何使用不同类型的索引测试插入/选择性能?i、 e.将STATO上的索引替换为(STATO,CAMPO47)或删除STATO和CAMPO47上的索引,并仅替换为一个索引(STATO,CAMPO47)。我认为Oracle应该用stato='SC'访问所有rowid,然后对campo47上的索引进行快速完整索引扫描,通过rowid搜索并直接返回Resultl,而根本不访问表。@APC您能给我发送一封电子邮件给sqlfiddle.com的管理员吗,您在sqlfiddle上发现的执行计划问题的一个示例?谢谢
AND campo47 >= chr(0)