持久化类可以定义一个或多个索引;其他数据结构用于提高操作(如排序或条件搜索)的效率。InterSystems SQL在执行查询时使用这些索引。InterSystems IRIS对象和SQL在执行INSERT、UPDATE和DELETE操作时自动维护索引内的正确值。
标准索引将一个或多个属性值的有序集与包含属性的对象的对象ID值相关联。
例如,假设我们定义了一个简单的持久化MyApp.Person类,该类具有两个文本属性和一个关于其Name属性的索引:
Class MyApp.Person Extends %Persistent { Index NameIdx On Name; Property Name As %String; Property Age As %Integer; }
如果我们创建并保存此Person类的多个实例,则生成的数据和索引全局变量类似于:
// data global ^MyApp.PersonD = 3 // counter node ^MyApp.PersonD(1) = $LB("",34,"Jones") ^MyApp.PersonD(2) = $LB("",22,"Smith") ^MyApp.PersonD(3) = $LB("",45,"Jones") // index global ^MyApp.PersonI("NameIdx"," JONES",1) = "" ^MyApp.PersonI("NameIdx"," JONES",3) = "" ^MyApp.PersonI("NameIdx"," SMITH",2) = ""
请注意有关全局索引的以下事项:
该索引包含足够的信息来满足许多查询,比如按姓名列出所有Person类。
位图索引位图索引类似于标准索引,不同之处在于它使用一系列位字符串来存储与索引值对应的一组对象ID值。
位字符串是一个包含一组特殊压缩格式的位(0和1值)的字符串。
InterSystems IRIS包含一组有效创建和使用位字符串的函数。
这些都列在下表中:
位操作
函数 | 描述 |
---|---|
$Bit | 在位串中设置或获取位。 |
$BitCount | 计算位串中的位数。 |
$BitFind | 查找位串中下一个出现的位。 |
$BitLogic | 对两个或多个位串执行逻辑(AND, OR)操作。 |
在位图索引中,位字符串中的顺序位置对应于索引表中的行(对象ID号)。
对于给定值,位图索引维护一个位字符串,在给定值存在的每一行中包含1,在没有给定值的每一行中包含0。
请注意,位图索引只适用于使用系统分配的默认存储结构的对象,数值型对象ID值。
例如,假设我们有一个类似如下的表:
ID | State | Product |
---|---|---|
1 | MA | Hat |
2 | NY | Hat |
3 | NY | Chair |
4 | MA | Chair |
5 | MA | Hat |
如果State和Product列有位图索引,则它们包含以下值:
State列上的位图索引包含以下位字符串值:
MA 1 0 0 1 1 NY 0 1 1 0 0
注意,对于值“MA”,在与State等于“MA”的表行对应的位置(1、4和5)中有一个1。
类似地,Product列上的位图索引包含以下位字符串值(注意,这些值在索引中被排序为大写):
CHAIR 0 0 1 1 0 HAT 1 1 0 0 1
InterSystems SQL Engine可以通过对这些索引维护的位串进行迭代、计算位内位数或执行逻辑组合(AND, or)来执行许多操作。
例如,要找到State等于“MA”、Product等于“HAT”的所有行,SQL引擎可以简单地将适当的位串与逻辑and组合在一起。
除了这些索引之外,系统还维护一个额外的索引,称为“区段索引”,对于存在的每一行包含1,对于不存在的行(如已删除的行)包含0。
这用于某些操作,如否定。
位图索引将一个或多个属性值的有序集合与一个或多个包含与属性值对应的对象ID值的位字符串相关联。
例如,假设我们定义了一个简单的持久MyApp。
Person类具有两个文字属性和Age属性上的位图索引:
Class MyApp.Person Extends %Persistent { Index AgeIdx On Age [Type = bitmap]; Property Name As %String; Property Age As %Integer; }
如果我们创建并保存这个Person类的几个实例,得到的数据和索引全局变量类似于:
// data global ^MyApp.PersonD = 3 // counter node ^MyApp.PersonD(1) = $LB("",34,"Jones") ^MyApp.PersonD(2) = $LB("",34,"Smith") ^MyApp.PersonD(3) = $LB("",45,"Jones") // index global ^MyApp.PersonI("AgeIdx",34,1) = 110... ^MyApp.PersonI("AgeIdx",45,1) = 001... // extent index global ^MyApp.PersonI("$Person",1) = 111... ^MyApp.PersonI("$Person",2) = 111...
关于全局索引,请注意以下几点:
另请注意:因为该表有一个位图索引,所以会自动维护一个区索引。该盘区索引存储在索引GLOBAL中,并使用前缀有“$”字符的类名作为其第一个下标。
下面的示例使用类区索引来计算存储的对象实例(行)的总数。注意,它使用$ORDER来迭代区索引的块(每个块包含大约64000行的信息):
ClassMethod Count1() As %Integer { New total,chunk,data Set total = 0 Set chunk = $Order(^Sample.PersonI("$Person",""),1,data) While (chunk '= "") { Set total = total + $bitcount(data,1) Set chunk = $Order(^Sample.PersonI("$Person",chunk),1,data) } Quit total }
DHC-APP>w ##class(PHA.TEST.SQL).Count1() 208