Rev*_*ous 3 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;
Run Code Online (Sandbox Code Playgroud)
我做了一个测试,将campo47字段添加到STATO索引中.性能从1 '49'上升到0,6s.
stato的索引不是选择性的.campo47上的索引(意思是field47)真的很有选择性.



你说CAMPO47是高度选择性的.但是你只是在IS NOT NULL上过滤.因此,它具有多少不同的值并不重要,优化器不会将其用作入口点.
它的选择性如何?从解释计划中的基数可以看出,选择STATO ='SC'会在表中找到12856行.这些行中有12702个明显具有CAMPO47值,因此只有154行被无效测试过滤掉.如果优化器已经为CAMPO47上的索引进行了操作,那么返回的行数是多少?可能还有很多.
优化器只能使用一个堆索引来访问表上的行.(当应用星形转换时,位图索引的机制不同).因此,如果您认为额外的表访问是一个令人难以忍受的负担,那么您有一个选项:复合索引.如果STATO真的是非选择性的(相对较少的行),那么你可以安全地用一个on(STATO,CAMPO47)替换现有的索引.
有一个老技巧,用于将数据库轻推到使用索引来访问IS NOT NULL操作,这就是使用一个操作数,只有在列包含值时才能为true.例如,对于字符串列这样的东西(我假设一个名为CAMPO47的东西只是一个字符串):
AND campo47 >= chr(0)
Run Code Online (Sandbox Code Playgroud)
这将匹配包含一个或多个ascii字符的任何列.不确定它是否会导致您描述的"两个索引"优化,但它值得一试.(我会自己测试一下,但我现在无法访问Oracle数据库,当我试图查看解释计划时,SQL Fiddle投掷了)