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(年龄,年龄上限(名称))
    上的索引可能值得维护它。但是如果是一张小桌子,或者你所有的朋友都是大学年龄的,那么你很可能不应该为任何索引而烦恼

    简而言之,这里有很多变量:您所能做的就是对各种选项进行基准测试,看看什么最适合您