第七章 SQL命令 CREATE INDEX(二)

第七章 SQL命令 CREATE INDEX(二)

UNIQUE关键字

使用UNIQUE关键字,可以指定索引中的每条记录都有一个唯一的值。
更具体地说,这确保了索引(以及包含索引的表)中的两条记录不能具有相同的排序值。
默认情况下,大多数索引使用大写字符串排序(使搜索不区分大小写)。
在本例中,值“Smith”“SMITH”被认为是相等的,而不是唯一的。
CREATE INDEX不能指定非默认索引字符串排序规则。
通过在类定义中定义索引,可以为各个索引指定不同的字符串排序规则。

可以更改名称空间的默认排序规则,使字段/属性在默认情况下区分大小写。
更改此选项需要重新编译命名空间中的所有类并重新构建所有索引。
转到Management Portal,选择Classes选项,为存储的查询选择名称空间,并使用Compile选项重新编译相应的类。
然后重建所有指数。
它们将区分大小写。

注意:当表的数据被其他用户访问时,不要重建索引。
这样做可能会导致不准确的查询结果。

BITMAP 关键字

使用BITMAP关键字,你可以指定这个索引将是位图索引。
位图索引由一个或多个位字符串组成,其中位位置表示行id,每个位值表示该行字段(或合并字段名字段的值)的特定值的存在(1)或不存在(0)。
SQL在插入、更新或删除数据时维护这些位置位(作为压缩位串);
在使用位图索引和使用常规索引之间,INSERTUPDATEDELETE操作的性能没有显著差异。
位图索引对于许多类型的查询操作都是非常高效的。
它们具有以下特点:

  • 只能在表(类)中定义位图索引,这些表(类)使用系统分配的 RowID 和正整数值,或者当 IDKEY 基于类型为 %IntegerMINVAL 的单个属性时使用主键 IDKEY 来定义自定义 ID> 0,或键入 %Numeric,其中 SCALE = 0MINVAL > 0

可以使用$SYSTEM.SQL.Util.SetOption()方法 SET status=$SYSTEM.SQL.Util.SetOption("BitmapFriendlyCheck",1,.oldval) 设置一个系统范围的配置参数,在编译时检查该限制,确定是否允许在%Storage.SQL中定义位图索引。
此检查仅适用于使用%Storage.SQL的类。
默认值是0。
可以使用$SYSTEM.SQL.Util.GetOption("BitmapFriendlyCheck")来确定该选项的当前配置。

只能为使用默认(%Storage.Persistent)结构的表定义位图索引。
具有复合键的表,例如子表,不能使用位图索引。
如果使用DDL(而不是使用类定义)来创建表,那么它就满足了这个要求,并且可以使用位图索引。

  • 位图索引应该只在可能的不同字段值的数量有限且相对较小的情况下使用。
    例如,对于性别、国籍或时区字段,位图索引是一个很好的选择。
    位图不应该在具有UNIQUE约束的字段上使用。
    如果一个字段可以有超过10,000个不同的值,或者多个索引字段可以有超过10,000个不同的值,那么就不应该使用位图。
  • 位图索引在WHERE子句中与逻辑ANDOR操作结合使用时非常有效。
    如果两个或多个字段通常被组合查询,那么为这些字段定义位图索引可能是有利的。

BITMAPEXTENT关键字

位图区段索引是表本身的位图索引。
SQL使用这个索引来提高COUNT(*)的性能,它返回表中记录(行)的数量。
一个表最多可以有一个位图扩展索引。
创建多个位图区段索引将导致一个带有%msgSQLCODE -400错误ERROR #5445: Multiple Extent indices defined: DDLBEIndex

所有使用CREATE TABLE定义的表都会自动定义位图范围索引。
这个自动生成的索引被分配为索引名称DDLBEIndexSQL MapName %%DDLBEIndex
定义为类的表可以有位图范围索引,索引名称和SQL MapName$ClassName

可以使用CREATE BITMAPEXTENT INDEX向表中添加位图区段索引,或者重命名自动生成的位图区段索引。
指定的index-name应该是表的table-name对应的类名。
这将成为索引的SQL MapName
不能指定字段名或WITH DATA子句。

以下示例使用索引名DDLBEIndexSQL MapName Patient创建位图区索引。如果Sample.Patient已具有%%DDLBEIndex位图区索引,则此示例将该索引重命名为SQL MapName Patient

  &sql(CREATE BITMAPEXTENT INDEX Patient ON TABLE Sample.Patient)
  WRITE !,"SQL code: ",SQLCODE

BITSLICE 关键字

使用BITSLICE关键字,可以指定此索引将是位片索引。位片索引专门用于计算中使用的数字数据。位片索引将每个数值数据值表示为二进制位串。位片索引不是使用布尔标志来索引数值数据值(就像在位图索引中那样),而是为每个数值创建一个位串,为每个记录创建一个单独的位串。这是一种高度专门化的索引类型,应该仅用于快速聚合计算。例如,以下内容将是位切片索引的候选对象:

SELECT SUM(Salary) FROM Sample.Employee

可以为字符串数据字段创建位片索引,但位片索引将这些数据值表示为规范数字。换句话说,任何非数字字符串(如“abc”)都将被索引为0。这种类型的位片索引可用于快速计数具有字符串字段值的记录,而不计算那些为空的记录。

不应在WHERE子句中使用位片索引,因为SQL查询优化器不使用位片索引。

使用INSERTUPDATEDELETE操作填充和维护位片索引比使用位图索引或常规索引慢得多。在频繁更新的字段上使用多个位片索引和/或使用位片索引可能具有显著的性能代价。

位片索引只能用于系统分配的行ID为正整数值的记录。位片索引只能用于单个字段名。不能指定WITH DATA子句。

重建索引

使用CREATE INDEX语句创建索引会自动构建索引。但是,在某些情况下,可能希望显式重新生成索引。

注意:如果其他用户正在访问表的数据,则在重建索引时必须采取其他步骤。如果不这样做,可能会导致查询结果不准确。有关更多详细信息,请参阅在活动系统上构建索引。

可以按如下方式构建/重新构建索引:

  • 使用构建索引SQL命令。
  • 使用管理门户重建指定类(表)的所有索引。
  • 使用%BuildIndices()方法。

要重建非活动表的所有索引,请执行以下操作:

  SET status = ##class(myschema.mytable).%BuildIndices()

默认情况下,此命令在重建索引之前清除索引。可以覆盖此清除默认值,并使用%PurgeIndices()方法显式清除指定的索引。如果对一定范围的ID值调用%BuildIndices(),则默认情况下 IRIS不会清除索引。

还可以清除/重建指定的索引:

  SET status = ##class(myschema.mytable).%BuildIndices($ListBuild("NameIDX","SpouseIDX"))

如上所述,如果索引损坏,可能需要清除/重建索引,或者更改索引的区分大小写。要重新压缩位图索引,请使用%SYS.Maint.Bitmap方法,而不是清除/重建。

示例

下面的嵌入式SQL示例创建了一个名为Fred的表,然后在Fred表的LastwordFirstword字段上创建了一个名为“FredIndex”的索引(通过从提供的名称“Fred_Index”中去掉标点)。

ClassMethod CreateIndex()
{
    &sql(
        CREATE TABLE Fred 
        (
            TESTNUM     INT NOT NULL,
            FIRSTWORD   CHAR (30) NOT NULL,
            LASTWORD    CHAR (30) NOT NULL,
            CONSTRAINT FredPK PRIMARY KEY (TESTNUM)
        )
    )
    if SQLCODE = 0 { 
        w !,"表创建" 
    } elseif SQLCODE = -201 { 
        w !,"表已经存在" 
    } else { 
        w !,"SQL表创建错误代码: ",SQLCODE
        q 
    }
    &sql(
        CREATE INDEX Fred_Index
        ON TABLE Fred
        (
            LASTWORD,FIRSTWORD
        )
    )
    if SQLCODE = -324 {
        w !,"索引已经存在" 
        q 
    } elseif SQLCODE = 0 { 
        w !,"创建索引" 
    } else { 
        w !,"SQL索引创建错误代码是: ",SQLCODE 
        q 
    }
}

下面的示例在Staff表的City字段上创建了一个名为“CityIndex”的索引:

CREATE INDEX CityIndex ON Staff (City)

下面的示例在Staff表的EmpName字段上创建了一个名为“EmpIndex”的索引。
UNIQUE约束用来避免在字段中有相同值的行:

CREATE UNIQUE INDEX EmpIndex ON TABLE Staff (EmpName)

下面的示例在Purchases表的SKU字段上创建一个名为“SKUIndex”的位图索引。
BITMAP关键字表示这是位图索引:

CREATE BITMAP INDEX SKUIndex ON TABLE Purchases (SKU)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容