ORACLE SQL索引性能
假设我们有以下查询:ORACLE SQL索引性能,sql,oracle,indexing,Sql,Oracle,Indexing,假设我们有以下查询: select name from friends where upper(name) like UPPER('%ESC%') and age = 20; 最好的索引方法是什么 创建好友索引fr(年龄、上级(姓名)) 在朋友(年龄)上创建索引fr 谢谢。最好的办法是什么?这两种方法几乎是等价的,尽管第一种方法对查询可能有很小的优势 在较高级别上,您只能索引age,因为like模式以通配符开头。因此,当age是索引的第一列时,Oracle可以使用该索引查找每个年龄合适的人 一
select name
from friends
where upper(name) like UPPER('%ESC%') and age = 20;
最好的索引方法是什么
创建好友索引fr(年龄、上级(姓名))代码>
在朋友(年龄)上创建索引fr代码>
谢谢。最好的办法是什么?这两种方法几乎是等价的,尽管第一种方法对查询可能有很小的优势 在较高级别上,您只能索引
age
,因为like
模式以通配符开头。因此,当age
是索引的第一列时,Oracle可以使用该索引查找每个年龄合适的人
一个小警告。如果您有第一个索引,Oracle可能足够聪明,不会应用upper(name)
函数,因为该值已经在索引中。Oracle仍然需要扫描索引中所有条目的age=20
,但不需要转到where
子句的数据页。这可能是一种节约,但通常不是很大的节约
如果查询是:
where upper(name) between 'ESC' and 'FSC' and age = 20;
那么第一个索引会更好,因为Oracle可以直接在索引中查找适当的行。可能两个索引都不能帮助您进行此查询 年龄似乎很有选择性。有一百多个不同的值(假设我们可以排除树木和建筑物作为朋友)。因此,对年龄的搜索似乎是在寻找所有可能记录的约1%。然而,年龄并不是均匀分布的:在
AGE=20
上的过滤器返回的记录可能比AGE=99
多得多
至于UPPER(NAME),您将限制在上,比如UPPER(“%ESC%”)
。塞斯克将与埃斯科巴和弗朗西斯卡并驾齐驱。因此,查询必须计算AGE=20
的每个姓名。如果您在friends(AGE,UPPER(NAME))
上有一个索引,那么可以使用索引范围扫描来计算整个WHERE子句,这将相当有效。仅AGE
上的索引将导致此时读取表
无论哪种方式,查询都需要读取表以获取整个记录,因为您希望返回名称
而不是上限(名称)
。如果您在AGE=20
上对一个公共名称元素进行了大量的点击,那么需要进行大量的索引读取,这是非常昂贵的。除非FRIENDS是一个非常宽的表(很多列),否则全表扫描读取整个表可能更有效
性能调优是一个权衡问题。如果您在FRIENDS中有很多记录,并且年龄分布很广,并且您想查询很多年龄和年龄上限(名称),那么FRIENDS(年龄,年龄上限(名称))
上的索引可能值得维护它。但是如果是一张小桌子,或者你所有的朋友都是大学年龄的,那么你很可能不应该为任何索引而烦恼
简而言之,这里有很多变量:您所能做的就是对各种选项进行基准测试,看看什么最适合您