搜索​​​​

清除过滤器
文章
姚 鑫 · 五月 9, 2021

第四章 多维存储的SQL和对象使用(一)

# 第四章 多维存储的SQL和对象使用(一) 本章介绍InterSystems IRIS®对象和SQL引擎如何利用多维存储(全局变量)来存储持久对象、关系表和索引。 尽管InterSystems IRIS对象和SQL引擎会自动提供和管理数据存储结构,但了解其工作原理的详细信息还是很有用的。 数据的对象视图和关系视图使用的存储结构是相同的。为简单起见,本章仅从对象角度介绍存储。 # 数据 每个使用`%Storage.Persistent`存储类(默认)的持久化类都可以使用多维存储(全局变量)的一个或多个节点在InterSystems IRIS数据库中存储其自身的实例。 每个持久化类都有一个存储定义,用于定义其属性如何存储在全局变量节点中。这个存储定义(称为“默认结构”)由类编译器自动管理。 ## 默认结构 用于存储持久对象的默认结构非常简单: - 数据存储在名称以完整类名(包括包名)开头的全局变量中。附加`“D”`以形成全局数据的名称,而附加`“I”`作为全局索引。 - 每个实例的数据都存储在全局数据的单个节点中,所有非瞬态属性都放在`$list`结构中。 - 数据全局变量中的每个节点都以对象`ID`值作为下标。默认情况下,对象`ID`值是通过调用存储在全局变量数据根(没有下标)的计数器节点上的`$Increment`函数提供的整数。 例如,假设我们定义了一个简单的持久化类`MyApp.Person`,它有两个文本属性: ```java Class MyApp.Person Extends %Persistent { Property Name As %String; Property Age As %Integer; } ``` 如果我们创建并保存此类的两个实例,得到的全局变量结果将类似于: ```java ^MyApp.PersonD = 2 // counter node ^MyApp.PersonD(1) = $LB("",530,"Abraham") ^MyApp.PersonD(2) = $LB("",680,"Philip") ``` **注意,存储在每个节点中的`$List`结构的第一部分是空的; 这是为类名保留的。 如果定义`Person`类的子类,则此槽包含子类名。 当多个对象存储在同一个区段内时,`%OpenId`方法(由`%Persistent`类提供)使用此信息多态地打开正确的对象类型。 此槽在类存储定义中显示为名为`“%%CLASSNAME”`的属性。** ## IDKEY `IDKEY`机制允许显式定义用作对象`ID`的值。为此,只需将`IDKEY`索引定义添加到类中,并指定将提供`ID`值的一个或多个属性。请注意,一旦保存对象,其对象`ID`值就不能更改。这意味着在保存使用`IDKEY`机制的对象后,不能再修改该对象`ID`所基于的任何特性。 ```java Class MyApp.Person Extends %Persistent { Index IDKEY On Name [ Idkey ]; Property Name As %String; Property Age As %Integer; } ``` 如果我们创建并保存`Person`类的两个实例,得到的全局变量结果现在类似于: ```java ^MyApp.PersonD("Abraham") = $LB("",530,"Abraham") ^MyApp.PersonD("Philip") = $LB("",680,"Philip") ``` 请注意,不再定义任何计数器节点。还要注意,通过将对象`ID`基于`Name`属性,我们已经暗示了`Name`的值对于每个对象必须是唯一的。 如果`IDKEY`索引基于多个属性,则主数据节点具有多个下标。例如: ```java Class MyApp.Person Extends %Persistent { Index IDKEY On (Name,Age) [ Idkey ]; Property Name As %String; Property Age As %Integer; } ``` 在这种情况下,生成的全局变量现在类似于: ```java ^MyApp.PersonD("Abraham",530) = $LB("",530,"Abraham") ^MyApp.PersonD("Philip",680) = $LB("",680,"Philip") ``` **重要提示:`IDKEY`索引使用的任何属性的值中都不能有连续的一对竖线(`||`),除非该属性是对持久类实例的有效引用。 这种限制是由InterSystems SQL机制的工作方式强加的。 在`IDKey`属性中使用`||`会导致不可预知的行为。** ## Subclasses 默认情况下,持久性对象的子类引入的任何字段都存储在附加节点中。 子类的名称用作附加的下标值。 例如,假设我们定义了一个具有两个文本属性的简单持久`MyApp.Person`类: ```java Class MyApp.Person Extends %Persistent { Property Name As %String; Property Age As %Integer; } ``` 现在,我们定义了一个持久子类`MyApp.Students`,它引入了两个额外的文本属性: ```java Class MyApp.Student Extends Person { Property Major As %String; Property GPA As %Double; } ``` 如果我们创建并保存此`MyApp.Student`类的两个实例,得到的全局结果将类似于: ```java ^MyApp.PersonD = 2 // counter node ^MyApp.PersonD(1) = $LB("Student",19,"Jack") ^MyApp.PersonD(1,"Student") = $LB(3.2,"Physics") ^MyApp.PersonD(2) = $LB("Student",20,"Jill") ^MyApp.PersonD(2,"Student") = $LB(3.8,"Chemistry") ``` 从`Person`类继承的属性存储在主节点中,而由`Student`类引入的属性存储在另一个子节点中。这种结构确保了学生数据可以作为人员数据互换使用。例如,列出所有`Person`对象名称的SQL查询正确地获取`Person`和`Student`数据。当属性被添加到超类或子类时,这种结构还使类编译器更容易维护数据兼容性。 请注意,主节点的第一部分包含字符串`“Student”`-它标识包含学生数据的节点。 ## 父子关系 在父子关系中,子对象的实例存储为它们所属的父对象的子节点。这种结构确保子实例数据与父数据在物理上是集群的。 ```java /// An Invoice class Class MyApp.Invoice Extends %Persistent { Property CustomerName As %String; /// an Invoice has CHILDREN that are LineItems Relationship Items As LineItem [inverse = TheInvoice, cardinality = CHILDREN]; } ``` 和`LineItem`: ```java /// A LineItem class Class MyApp.LineItem Extends %Persistent { Property Product As %String; Property Quantity As %Integer; /// a LineItem has a PARENT that is an Invoice Relationship TheInvoice As Invoice [inverse = Items, cardinality = PARENT]; } ``` 如果我们存储多个`Invoice`对象的实例,每个实例都有关联的`LineItem`对象,则得到的全局变量结果将类似于: ```java ^MyApp.InvoiceD = 2 // invoice counter node ^MyApp.InvoiceD(1) = $LB("","Wiley Coyote") ^MyApp.InvoiceD(1,"Items",1) = $LB("","Rocket Roller Skates",2) ^MyApp.InvoiceD(1,"Items",2) = $LB("","Acme Magnet",1) ^MyApp.InvoiceD(2) = $LB("","Road Runner") ^MyApp.InvoiceD(2,"Items",1) = $LB("","Birdseed",30) ``` ## 嵌入对象 存储嵌入对象的方法是先将它们转换为序列化状态(默认情况下是包含对象属性的`$List`结构),然后以与任何其他属性相同的方式存储此串行状态。 例如,假设我们定义了一个具有两个文字属性的简单串行(可嵌入)类: ```java Class MyApp.MyAddress Extends %SerialObject { Property City As %String; Property State As %String; } ``` 现在,我们修改前面的示例以添加嵌入的`Home Address`属性: ```java Class MyApp.MyClass Extends %Persistent { Property Name As %String; Property Age As %Integer; Property Home As MyAddress; } ``` 如果我们创建并保存此类的两个实例,则生成的全局变量相当于: ```java ^MyApp.MyClassD = 2 // counter node ^MyApp.MyClassD(1) = $LB(530,"Abraham",$LB("UR","Mesopotamia")) ^MyApp.MyClassD(2) = $LB(680,"Philip",$LB("Bethsaida","Israel")) ``` ## 流 **通过将全局流的数据拆分成一系列块(每个块小于`32K`字节)并将这些块写入一系列顺序节点,全局流被存储在全局流中。文件流存储在外部文件中。**
文章
姚 鑫 · 五月 10, 2021

第四章 多维存储的SQL和对象使用(二)

# 第四章 多维存储的SQL和对象使用(二) # 索引 持久化类可以定义一个或多个索引;其他数据结构用于提高操作(如排序或条件搜索)的效率。InterSystems SQL在执行查询时使用这些索引。InterSystems IRIS对象和SQL在执行`INSERT`、`UPDATE`和`DELETE`操作时自动维护索引内的正确值。 ## 标准索引的存储结构 标准索引将一个或多个属性值的有序集与包含属性的对象的对象`ID`值相关联。 例如,假设我们定义了一个简单的持久化`MyApp.Person`类,该类具有两个文本属性和一个关于其`Name`属性的索引: ```java Class MyApp.Person Extends %Persistent { Index NameIdx On Name; Property Name As %String; Property Age As %Integer; } ``` 如果我们创建并保存此`Person`类的多个实例,则生成的数据和索引全局变量类似于: ```java // 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) = "" ``` 请注意有关全局索引的以下事项: 1. 默认情况下,它被放在一个全局变量中,全局变量的名称是后面附加`“i”`(表示索引)的类名。 2. 默认情况下,第一个下标是索引名;这允许将多个索引存储在同一全局中,而不会发生冲突。 3. 第二个下标包含整理后的数据值。在这种情况下,使用默认的`SQLUPPER`排序函数对数据进行排序。这会将所有字符转换为大写(不考虑大小写进行排序),并在前面加上一个空格字符(强制所有数据作为字符串进行排序)。 4. 第三个下标包含包含索引数据值的对象的对象ID值。 5. 节点本身是空的;所有需要的数据都保存在下标中。请注意,如果索引定义指定数据应与索引一起存储,则将其放置在全局索引的节点中。 该索引包含足够的信息来满足许多查询,比如按姓名列出所有`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`属性上的位图索引: ```java Class MyApp.Person Extends %Persistent { Index AgeIdx On Age [Type = bitmap]; Property Name As %String; Property Age As %Integer; } ``` 如果我们创建并保存这个`Person`类的几个实例,得到的数据和索引全局变量类似于: ```java // 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... ``` 关于全局索引,请注意以下几点: 1. 默认情况下,它被放置在一个全局变量中,全局变量的名称是类名,后面附加一个`“I”`(表示`Index`)。 2. 默认情况下,第一个下标是索引名;这允许多个索引存储在同一个全局中,而不会发生冲突。 3. 第二个下标包含经过整理的数据值。在这种情况下,不应用排序函数,因为这是数字数据的索引。 4. **第三个下标包含块编号;为了提高效率,位图索引被分成一系列位串,每个位串包含表中大约`64000`行的信息。这些位串中的每一个都被称为块。** 5. 节点包含位串。 另请注意:因为该表有一个位图索引,所以会自动维护一个区索引。该盘区索引存储在索引`GLOBAL`中,并使用前缀有`“$”`字符的类名作为其第一个下标。 ## 位图索引的直接访问 下面的示例使用类区索引来计算存储的对象实例(行)的总数。注意,它使用`$ORDER`来迭代区索引的块(每个块包含大约64000行的信息): ```java 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 } ``` ```java DHC-APP>w ##class(PHA.TEST.SQL).Count1() 208 ```
文章
姚 鑫 · 四月 1, 2021

第十四章 使用SQL Shell界面(三)

# 第十四章 使用SQL Shell界面(三) # SQL元数据、查询计划和性能指标 ## 显示元数据 SQL Shell支持`M`或`Metadata`命令以显示有关当前查询的元数据信息。 对于每个结果集项目,此命令列出以下元数据:列名称(SQL字段名称),键入(ODBC数据类型整数代码),PRE(精度或最大长度),比例(最大分数数字),`NULL(BOOLEAN:1 = NULL允许,0 =不允许空值)`,标签(标题标签,请参阅列别名),表(SQL表名称),架构(架构名称),`CTYPE`(客户端数据类型,请参阅`%SQL.statementColumn ClientType`属性)。 ## SHOW STATEMENT 可以执行查询,然后发出show语句或显示`st`以显示准备好的SQL语句。默认情况下,必须执行查询。可以避免通过设置`executemode =延迟`执行查询,从而发出查询,然后发出`show`语句sql shell命令。 显示声明信息包含实现类(缓存查询名称),参数(一个以逗号分隔的实际参数值,如上面条款和`WHERE`子句文字值),和语句文本(文字文本的SQL命令,包括字母大小写和参数值)。 ## EXPLAIN and Show Plan 有两种方式显示SQL查询的查询计划; 如果需要,两者都可以显示备用的查询计划。 - EXPLAIN:前言用解释命令选择SELECT查询。例如: ```sql SQL]USER>>EXPLAIN SELECT Name FROM Sample.MyTable WHERE Name='Fred Rogers' ``` - SHOW PLAN:发出查询,然后发出show plan shell命令。例如: ```sql SQL]USER>>SELECT Name FROM Sample.MyTable WHERE Name='Fred Rogers' SQL]USER>>SHOW PLAN ``` EXPLAIN SQL命令显示有关指定选择查询的查询计划信息而不执行查询。EXPLAIN Alt允许显示备用查询计划。EXPLAIN Stat返回性能统计信息以及查询计划。EXPLAIN只能用于返回选择查询的查询计划;它不会返回用于执行查询操作的`Insert`,`Update`或`DELETE`语句等其他命令的查询计划。 Show Plan SQL shell命令允许显示SQL Shell成功发布的上次查询的查询计划信息。显示计划可用于执行查询操作的任何SQL命令,包括选择,插入,更新和删除。默认情况下,必须执行查询。可以避免通过设置`executemode=deferred`,执行查询,发出查询,然后发出以下SQL shell命令之一: - SHOW PLAN、SHOW PL(或简单的SHOW)显示关于当前查询的查询计划信息。 查询计划可用于调试和优化查询的性能。 它指定查询的执行方式,包括索引的使用和查询的成本值。 可以返回查询计划的语句有:`SELECT`、`DECLARE`、`non-cursor UPDATE or DELETE`、`INSERT…SELECT`。 该命令有一个`V` (VERBOSE)选项。 - 显示PLANALT显示当前查询的备用显示计划。 该命令有一个`V` (VERBOSE)选项。 可以使用`$SYSTEM.SQL.Explain()`方法从ObjectScript生成查询计划。 ## SQL Shell Performance 成功执行一个SQL语句后,SQL Shell会显示四个语句准备值(`times(s)/globals/cmds/disk`)和四个语句执行值(`times(s)/globals/cmds/disk`): - 语句准备时间是指准备动态语句所花费的时间。 这包括生成和编译语句所花费的时间。 它包括在语句缓存中查找语句所花费的时间。 因此,如果执行了一条语句,然后按编号或名称回收,回收语句的准备时间接近于零。 如果一条语句已经准备好并执行,然后通过发出GO命令重新执行,那么重新执行时的准备时间为零。 - 经过的执行时间是从调用`%execute()`到`%Display()`返回所经过的时间。 它不包括输入参数值的等待时间。 语句`globals`是全局引用的计数,`cmds`是执行的SQL命令的计数,`disk`是磁盘延迟时间,单位是毫秒。 SQL Shell为准备操作和执行操作保留单独的计数。 这些性能值只在`“DISPLAYMODE”`设置为`“currentdevice”`,`“MESSAGES”`设置为`“ON”`时显示。 这些是SQL Shell的默认设置。 # Transact-SQL支持 默认情况下,SQL Shell执行InterSystems SQL代码。 但是,SQL Shell可以用来执行`Sybase`或MSSQL代码。 ## Setting DIALECT 默认情况下,SQL Shell将代码解析为InterSystems SQL。 可以使用`SET DIALECT`来配置SQL Shell以执行`Sybase`或`MSSQL`代码。 若要更改当前方言,请将`“方言”`设置为`Sybase`、`MSSQL`或IRIS。 默认值是`Dialect=IRIS`。 这些设置的方言选项不区分大小写。 下面是一个从SQL Shell中执行MSSQL程序的例子: ```java DHC-APP>DO $SYSTEM.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: . Enter q to quit, ? for help. DHC-APP>>SET DIALECT MSSQL dialect = MSSQL DHC-APP>>SELECT TOP 5 name + '-' + ssn FROM Sample.Person 1. SELECT TOP 5 name + '-' + ssn FROM Sample.Person Expression_1 yaoxin-111-11-1117 xiaoli-111-11-1111 姚鑫-111-11-1112 姚鑫-111-11-1113 姚鑫-111-11-1114 5 Rows(s) Affected statement prepare time(s)/globals/lines/disk: 0.1989s/46546/257369/114ms execute time(s)/globals/lines/disk: 0.0032s/24/676/3ms --------------------------------------------------------------------------- ``` `Sybase`和`MSSQL`方言支持这些方言中有限的SQL语句子集。 它们支持`SELECT`、`INSERT`、`UPDATE`和`DELETE`语句。 它们对永久表支持`CREATE TABLE`语句,但对临时表不支持。 支持创建视图。 支持创建触发器和删除触发器。 但是,如果`CREATE TRIGGER`语句部分成功,但在类编译时失败,则此实现不支持事务回滚。 支持`CREATE PROCEDURE`和`CREATE FUNCTION`。 ## Setting COMMANDPREFIX 可以使用`SET COMMANDPREFIX`指定必须追加到后续SQL Shell命令的前缀(通常是单个字符)。 在SQL Shell提示符发出的SQL语句中不使用此前缀。 这个前缀的目的是防止SQL Shell命令和SQL代码语句之间的歧义。 例如,`SET`是一个SQL Shell命令; `SET`也是`Sybase`和`MSSQL`中的SQL代码语句。 默认情况下,没有命令前缀。 要建立命令前缀,设置`COMMANDPREFIX=prefix`,指定的前缀不带引号。 要恢复为没有命令前缀,设置`COMMANDPREFIX=""`。 以下示例显示了命令前缀/(斜杠字符)被设置、使用和恢复的示例: ```java DHC-APP>>SET COMMANDPREFIX=/ commandprefix = / DHC-APP>>/SET LOG=ON log = xsql19388.log DHC-APP>> > 1>>SELECT TOP 3 Name,Age 2>>FROM Sample.Person 3>>/GO 2. SELECT TOP 3 Name,Age FROM Sample.Person Name Age yaoxin 30 xiaoli 姚鑫 7 3 Rows(s) Affected statement prepare time(s)/globals/lines/disk: 0.0595s/46282/256257/9ms execute time(s)/globals/lines/disk: 0.0003s/3/714/0ms --------------------------------------------------------------------------- DHC-APP>>/SET COMMANDPREFIX commandprefix = / DHC-APP>>/SET COMMANDPREFIX="" commandprefix = "" DHC-APP>>SET COMMANDPREFIX commandprefix = ``` 当设置了命令前缀时,除了`?`、`#`和`GO`之外的所有SQL Shell命令都需要该命令前缀; 可以使用或不使用命令前缀发出这三个SQL Shell命令。 当发出`SET`或`SET COMMANDPREFIX`命令时,SQL Shell将显示当前命令前缀,作为SQL Shell初始化的一部分,并且在`?` 命令选项显示。 ## 运行命令 SQL Shell `RUN`命令执行SQL脚本文件。 在发出运行命令之前必须设置方言,以指定IRIS (InterSystems SQL)、Sybase (Sybase TSQL)或MSSQL (Microsoft SQL); 默认的方言是IRIS。 可以调用`RUN scriptname`,也可以只调用`RUN`,然后提示输入脚本文件名。 `RUN`加载脚本文件,然后准备并执行文件中包含的每个语句。 脚本文件中的语句必须分隔,通常用`GO`行或分号(`;`)分隔。 `RUN`命令提示指定分隔符。 SQL脚本文件结果显示在当前设备上,也可以显示在日志文件中。 还可以生成一个包含准备失败语句的文件。 `RUN`命令返回指定这些选项的提示符,示例如下: ```java [SQL]USER>>SET DIALECT=Sybase dialect = Sybase [SQL]USER>>RUN Enter the name of the SQL script file to run: SybaseTest Enter the file name that will contain a log of statements, results and errors (.log): SyTest.log SyTest.log Many script files contain statements not supported by IRIS SQL. Would you like to log the statements not supported to a file so they can be dealt with manually, if applicable? Y=> y Enter the file name in which to record non-supported statements (_Unsupported.log): SyTest_Unsupported.log Please enter the end-of-statement delimiter (Default is 'GO'): GO=> Pause how many seconds after error? 5 => 3 Sybase Conversion Utility (v3) Reading source from file: Statements, results and messages will be logged to: SyTest.log . . . ``` ## TSQL例子 下面的SQL Shell示例创建了一个`Sybase`过程`AvgAge`。 它使用`Sybase EXEC`命令执行这个过程。 然后,它将方言更改为InterSystems IRIS,并使用InterSystems SQL `CALL`命令执行相同的过程。 ```java DHC-APP>>SET DIALECT Sybase dialect = Sybase DHC-APP>> > 1>>CREATE PROCEDURE AvgAge 2>>AS SELECT AVG(Age) FROM Sample.Person 3>>GO 3. CREATE PROCEDURE AvgAge AS SELECT AVG(Age) FROM Sample.Person statement prepare time(s)/globals/lines/disk: 0.0173s/8129/22308/4ms execute time(s)/globals/lines/disk: 0.0436s/3844/23853/34ms --------------------------------------------------------------------------- DHC-APP>>EXEC AvgAge 4. EXEC AvgAge Dumping result #1 Aggregate_1 50.68137254901960784 1 Rows(s) Affected statement prepare time(s)/globals/lines/disk: 0.0086s/8096/21623/0ms execute time(s)/globals/lines/disk: 0.1131s/90637/458136/19ms --------------------------------------------------------------------------- DHC-APP>>SET DIALECT=IRIS Dialect 'iris' is not supported. ```
文章
姚 鑫 · 四月 22, 2021

第五章 优化查询性能(一)

# 第五章 优化查询性能(一) InterSystems SQL自动使用查询优化器创建在大多数情况下提供最佳查询性能的查询计划。该优化器在许多方面提高了查询性能,包括确定要使用哪些索引、确定多个`AND`条件的求值顺序、在执行多个联接时确定表的顺序,以及许多其他优化操作。可以在查询的`FROM`子句中向此优化器提供“提示”。本章介绍可用于评估查询计划和修改InterSystems SQL将如何优化特定查询的工具。 InterSystems IRIS®Data Platform支持以下优化SQL查询的工具: - `SQL Runtime Statistics`用于生成查询执行的运行时性能统计信息 - 索引分析器,用于显示当前命名空间中所有查询的各种索引分析器报告。这显示了InterSystems SQL将如何执行查询,可以全面了解索引是如何使用的。此索引分析可能表明应该添加一个或多个索引以提高性能。 - 查询执行计划:显示SQL查询(查询计划)的最佳(默认)执行计划,并可选地显示该SQL查询的备用查询计划以及统计信息。用于显示查询计划的工具包括SQL `EXPLAIN`命令、`$SYSTEM.SQL.ExPlan()`方法以及管理门户和SQL Shell中的各种`Show Plan`工具。查询计划和统计数据是在准备查询时生成的,不需要执行查询。 可以使用以下选项来指导查询优化器,方法是设置配置默认值或在查询代码中编码优化器“提示”: - 管理所有条件的子句选项中提供的索引优化选项,或单个条件前面的`%NOINDEX`。 - SQL代码中指定的注释选项,使优化器覆盖该查询的系统范围编译选项。 - 在每个查询或系统范围的基础上可用的并行查询处理允许多处理器系统在处理器之间划分查询执行。 以下SQL查询性能工具将在本手册的其他章节中介绍: - 缓存查询,使动态SQL查询能够重新运行,而无需在每次执行查询时准备查询的开销。 - SQL语句来保留最新编译的嵌入式SQL查询。在“SQL语句和冻结计划”一章中。 - 冻结计划以保留嵌入式SQL查询的特定编译。使用此编译,而不是使用较新的编译。在“SQL语句和冻结计划”一章中。 以下工具用于优化表数据,因此可以对针对该表运行的所有查询产生重大影响: - 定义索引可以显著提高对特定索引字段中数据的访问速度。 - `ExtentSize`、`Selective`和`BlockCount`用于在用数据填充表之前指定表数据估计;此元数据用于优化未来的查询。 - `Tune Table`用于分析已填充的表中的代表性表数据;生成的元数据用于优化未来的查询。 本章还介绍如何将查询优化计划写入文件,以及如何生成SQL故障排除报告以提交给InterSystems WRC。 # 管理门户SQL性能工具 IRIS管理门户提供对以下SQL性能工具的访问。有两种方式可以从管理门户系统资源管理器选项访问这些工具: - 选择工具,然后选择SQL性能工具。 - 选择SQL,然后选择工具下拉菜单。 从任一界面中您都可以选择以下SQL性能工具之一: - SQL运行时统计信息,以生成查询执行的性能统计信息。 - 索引分析器,用于显示当前命名空间中所有查询的各种索引分析器报告。这显示了InterSystems SQL将如何执行查询,可以全面了解索引是如何使用的。此索引分析可能表明应该添加一个或多个索引以提高性能。 - 备用显示计划:显示SQL查询的可用备用查询计划以及统计信息。 - 生成报告以向InterSystems Worldwide Response Center(WRC)客户支持部门提交SQL查询性能报告。要使用此报告工具,必须首先从WRC获得WRC跟踪号。 - 导入报告允许查看SQL查询性能报告。 # SQL运行时统计信息 可以使用SQL运行时统计信息来衡量系统上运行的SQL查询的性能。SQL运行时统计信息衡量`SELECT`、`INSERT`、`UPDATE`和`DELETE`操作(统称为查询操作)的性能。SQL运行时统计信息(SQL Stat)是在准备查询操作时收集的。请参阅使用SQL运行时统计信息工具。 默认情况下,SQL运行时统计信息的收集处于关闭状态。必须激活统计信息收集。强烈建议指定超时以结束统计信息收集。激活统计信息收集后,必须重新编译(准备)现有的动态SQL查询,并重新编译包含嵌入式SQL的类和例程。 性能统计信息包括`ModuleName`、`ModuleCount`(模块被调用的次数)、`RowCount`(返回的行数)、`TimeSpent`(执行性能,单位为秒)、`GlobalRefs`(全局引用数)、`LinesOfCode`(执行的行数)和`ReadLatency`(磁盘读取访问时间,单位为毫秒)。 可以显式清除SQL Stats数据。清除缓存查询会删除所有相关的SQL统计数据。删除表或视图会删除所有相关的SQL Stats数据。 注意:系统任务在所有名称空间中每小时自动运行一次,以将特定于进程的SQL查询统计信息聚合到全局统计信息中。因此,全局统计信息可能不会反映一小时内收集的统计信息。可以使用管理门户监视此每小时一次的聚合或强制其立即发生。要查看此任务上次完成和下次调度的时间,请依次选择系统操作、任务管理器、任务调度,然后查看更新SQL查询统计信息任务。可以单击任务名称查看任务详细信息。在`Task Details`(任务详细信息)显示中,可以使用Run(运行)按钮强制立即执行任务。 # 使用SQL运行时统计信息工具 可以使用以下任一方法从管理门户显示系统范围内的SQL查询的性能统计信息: - 选择系统资源管理器,选择工具,选择SQL性能工具,然后选择SQL运行时统计信息。 ![image](/sites/default/files/inline/images/1_38.png) - 选择系统资源管理器,选择SQL,然后从工具下拉菜单中选择SQL运行时统计信息。 ## Settings “设置”选项卡显示当前系统范围的SQL运行时统计信息设置以及此设置的过期时间。 Change Settings(更改设置)按钮允许设置以下统计信息收集选项: - 收集选项:可以将统计信息收集选项设置为0、1、2或3.0。0=关闭统计信息代码生成;1=为所有查询打开统计信息代码生成,但不收集统计信息;2=仅记录查询外部循环的统计信息(在主模块打开和关闭时收集统计信息);3=记录查询的所有模块级别的统计信息。 - 从0到1:更改SQL Stats选项后,需要编译包含SQL的例程和类以执行统计代码生成。对于xDBC和动态SQL,必须清除缓存查询以强制重新生成代码。 - 要从1变为2:只需更改SQL Stats选项即可开始收集统计信息。这使可以在运行的生产环境中启用SQL性能分析,并将中断降至最低。 - 从1到3(或从2到3):更改SQL Stats选项后,需要编译包含SQL的例程和类,以记录所有模块级别的统计信息。对于xDBC和动态SQL,必须清除缓存查询以强制重新生成代码。选项3通常仅用于非生产环境中已识别的性能较差的查询。 - 从1、2或3变为0:要关闭统计代码生成,不需要清除缓存的查询。 - 超时选项:如果收集选项为2或3,可以按已用时间(小时或分钟)或按完成日期和时间指定超时。可以用分钟或小时和分钟指定运行时间;该工具将指定的分钟值转换为小时和分钟(100分钟=1小时40分钟)。默认值为50分钟。日期和时间选项默认为当天午夜(23:59)之前。强烈建议指定超时选项。 - 重置选项:如果收集选项为2或3,则可以指定超时值到期时要重置为的收集选项。可用选项为0和1。 ## 查询测试 查询测试选项卡允许输入SQL查询文本(或从历史记录中检索),然后显示该查询的SQL统计信息和查询计划。查询测试包括查询的所有模块级别的SQL统计信息,而与收集选项设置无关。 输入一个SQL查询文本,或使用`Show History`按钮检索一个。 可以通过单击右边的圆形“X”圆来清除查询文本字段。 使用`Show Plan With SQL Stats`按钮执行。 默认情况下,后台复选框中的“运行`Show Plan`进程”未被选中,这是大多数查询的首选设置。 仅对长时间、运行缓慢的查询选择此复选框。 当这个复选框被选中时,你会看到一个进度条显示“请等待…”的消息。 当运行一个长查询时,带有SQL Stats和`Show History`按钮的`Show Plan`消失,而显示一个`View Process`按钮。 单击`View Process`将在新选项卡中打开流程详细信息页面。 在流程详细信息页面中,可以查看该流程,并可以暂停、恢复或终止该流程。 流程的状态应该反映在显示计划页面上。 当流程完成后,显示计划会显示结果。 `View Process`按钮消失,带有SQL Stats的`Show Plan`和`Show History`按钮重新出现。 使用查询测试显示的语句文本包括注释,不执行文字替换。 ## 查看统计信息 `View Stats`(查看统计信息)选项卡为提供了在此系统上收集的运行时统计信息的总体视图。 可以单击任何一个`View Stats`列标题对查询统计信息进行排序。然后,可以单击SQL语句文本以查看所选查询的详细查询统计信息和查询计划。 使用此工具显示的语句文本包括注释,不执行文字替换。`ExportStatsSQL()`和`Show Plan`显示的语句文本会去掉注释并执行文字替换。 ### 清除统计信息按钮 清除统计信息按钮清除当前名称空间中所有查询的所有累积统计信息。它会在SQL运行时统计信息页上显示一条消息。如果成功,则会显示一条消息,指示已清除的统计信息数量。如果没有统计信息,则会显示无要清除的消息。如果清除不成功,则会显示一条错误消息。 ## 运行时统计信息和显示计划 SQL运行时统计信息工具可用于显示包含运行时统计信息的查询的显示计划。 可以使用`Alternate Show Plans`工具将显示计划与统计数据进行比较,从而显示查询的运行时统计信息。备用显示计划工具在其显示计划选项中显示查询的估计统计信息。如果激活了收集运行时统计信息,则其`Compare Show Plans with Stats`选项将显示实际的运行时统计信息;如果运行时统计信息未处于活动状态,则此选项将显示估计统计信息。
文章
姚 鑫 · 五月 20, 2021

第一章 发送HTTP请求

# 第一章 发送HTTP请求 本主题介绍如何发送`HTTP`请求(如`POST`或`GET`)和处理响应。 # HTTP请求简介 可以创建`%Net.HttpRequest`的实例来发送各种`HTTP`请求并接收响应。此对象相当于Web浏览器,可以使用它发出多个请求。它会自动发送正确的`cookie`,并根据需要设置`Referer`标头。 要创建HTTP请求,请使用以下常规流程: 1. 创建`%Net.HttpRequest`的实例。 2. 设置此实例的属性以指示要与之通信的Web服务器。基本属性如下: - 服务器指定Web服务器的IP地址或计算机名称。默认值为`localhost`。 **注意:不要将`http://`或`https://`作为服务器值的一部分。这将导致错误`#6059:无法打开到服务器http:/的TCP/IP套接字`。** 3. 可以选择设置HTTP请求的其他属性和调用方法,如指定其他HTTP请求属性中所述。 4. 然后,通过调用`%Net.HttpRequest`实例的`get()`方法或其他方法来发送HTTP请求,如“发送HTTP请求”中所述。 可以从实例发出多个请求,它将自动处理cookie和Referer标头。 注意:如果创建此HTTP请求是为了与生产出站适配器(`EnsLib.HTTP.Outbound Adapter`)一起使用,那么请改用该适配器的方法来发送请求。 5. 如果需要,使用`%Net.HttpRequest`的同一实例发送其他HTTP请求。默认情况下,InterSystems IRIS使TCP/IP套接字保持打开状态,以便可以重复使用套接字,而无需关闭和重新打开它。 以下是一个简单的示例: ```java /// w ##class(PHA.TEST.HTTP).Get() ClassMethod Get() { set request=##class(%Net.HttpRequest).%New() set request.Server="tools.ietf.org" set request.Https=1 set request.SSLConfiguration="yx" set status=request.Get("/html/rfc7158") d $System.Status.DisplayError(status) s response = request.HttpResponse s stream = response.Data q stream.Read() } ``` # 提供身份验证 如果目标服务器需要登录凭据,则HTTP请求可以包括提供凭据的HTTP `Authorization`标头。 如果使用的是代理服务器,还可以指定代理服务器的登录凭据;为此,请设置`ProxyAuthorization`属性 ## 使用HTTP 1.0时对请求进行身份验证 对于HTTP 1.0,要验证HTTP请求,请设置`%Net.HttpRequest`实例的用户名和密码属性。然后,该实例使用基本访问身份验证基于该用户名和密码创建HTTP `Authorization`标头(RFC 2617)。此`%Net.HttpRequest`发送的任何后续请求都将包括此头。 **重要提示:请确保还使用SSL。在基本身份验证中,凭据以base-64编码形式发送,因此易于读取。** ## 在使用HTTP 1.1时对请求进行身份验证 对于HTTP 1.1,要验证HTTP请求,在大多数情况下,只需设置`%Net.HttpRequest`实例的用户名和密码属性。当`%Net.HttpRequest`的实例收到`401 HTTP`状态代码和`WWW-Authenticate`标头时,它会尝试使用包含支持的身份验证方案的`Authorization`标头进行响应。使用为IRIS支持和配置的第一个方案。默认情况下,它按以下顺序考虑这些身份验证方案: 1. 协商(SPNEGO和Kerberos,根据RFC 4559和RFC 4178) 2. NTLM(NT LAN Manager身份验证协议) 3. 基本认证(RFC 2617中描述的基本接入认证) 重要:如果有可能使用基本身份验证,请确保也使用SSL(参见“使用SSL进行连接”)。 在基本身份验证中,凭据以base-64编码的形式发送,因此很容易读取。 在Windows上,如果没有指定`Username`属性,IRIS可以使用当前登录上下文。 具体来说,如果服务器使用401状态码和用于`SPNEGO`、`Kerberos`或`NTLM`的`WWW-Authenticate`头响应,那么IRIS将使用当前操作系统用户名和密码创建`Authorization`头。 具体情况与HTTP 1.0不同,如下所示: 1. 如果认证成功,IRIS更新`%Net`的`CurrentAuthenticationScheme`属性。 `HttpRequest`实例来指示它在最近的身份验证中使用的身份验证方案。 2. 如果尝试获取方案的身份验证句柄或令牌失败,IRIS会将基础错误保存到`%Net.HttpRequest`实例的`AuthenticationErrors`属性中。此属性的值为`$List`,其中每一项都具有格式`scheme ERROR: message` 仅HTTP 1.1支持协商和`NTLM`,因为这些方案需要多次往返,而HTTP 1.0要求在每个请求/响应对之后关闭连接。 ### Variations 如果知道服务器允许的一个或多个身份验证方案,则可以通过包括`Authorization`标头来绕过服务器的初始往返行程,该标头包含所选方案的服务器的初始令牌。为此,请设置`%Net.HttpRequest`实例的`InitiateAuthentication`属性。对于此属性的值,请指定服务器允许的单个授权方案的名称。使用下列值之一(区分大小写): - Negotiate - NTLM - Basic 如果要自定义要使用的身份验证方案(或更改其考虑顺序),请设置`%Net.HttpRequest`实例的`AuthenticationSchemes`。对于此属性的值,请指定以逗号分隔的身份验证方案名称列表(使用上一个列表中给出的准确值)。 ## 直接指定授权标头 对于HTTP 1.0或HTTP 1.1(如果适用于场景),可以直接指定HTTP `Authorization`标头。具体地说,可以将`Authorization`属性设置为等于正在请求的资源的用户代理所需的身份验证信息。 如果指定`Authorization`属性,则忽略用户名和密码属性。 ## 启用HTTP身份验证的日志记录 要启用HTTP身份验证的日志记录,请在终端中输入以下内容: ```java set $namespace="%SYS" kill ^ISCLOG set ^%ISCLOG=2 set ^%ISCLOG("Category","HttpRequest")=5 ``` 日志条目将写入`^ISCLOG global`中.。要将日志写入文件(以提高可读性),请输入以下内容(仍在`%SYS`命名空间内): ```java do ##class(%OAuth2.Utils).DisplayLog("filename") ``` 其中,`filename`是要创建的文件的名称。该目录必须已存在。如果该文件已经存在,它将被覆盖。 要停止日志记录,请输入以下内容(仍在`%SYS`命名空间内): ```java set ^%ISCLOG=0 set ^%ISCLOG("Category","HttpRequest")=0 ``` # 指定其他HTTP请求属性 在发送HTTP请求之前(请参阅发送HTTP请求),可以指定其属性,如以下各节所述: 可以为`%Net.HttpRequest`的所有属性指定默认值,如最后列出的部分中所指定。 ## Location属性 `Location`属性指定从Web服务器请求的资源。如果设置此属性,则在调用`Get()`, `Head()`, `Post()`, 或 `Put()`方法时,可以省略location参数。 例如,假设正在向url `http://machine_name/test/index.html`发送一个HTTP请求 在这种情况下,将使用下列值: `%Net.HttpRequest`的示例属性 Properties |Value ---|--- Server| machine_name Location| test/index.html ## 指定Internet媒体类型(Media Type)和字符编码(Character Encoding) 可以使用以下属性指定`%Net.HttpRequest`实例及其响应中的Internet媒体类型(也称为MIME类型)和字符编码: - Content-Type指定`Content-Type`标头,该标头指定请求正文的Internet媒体类型。默认类型为None。 可能的值包括`application/json`、`application/pdf`、`application/postscript`、`image/jpeg`、`image/png`、`multipart/form-data`、`text/html`、`text/plan`、`text/xml`等等 - ContentCharset属性控制请求的任何内容(例如,`text/html`或`text/xml`)类型时所需的字符集。如果不指定此属性,InterSystems IRIS将使用InterSystems IRIS服务器的默认编码。 注意:如果设置此属性,则必须首先设置`ContentType`属性。 - `NoDefaultContentCharset`属性控制在未设置`ContentCharset`属性的情况下是否包括文本类型内容的显式字符集。默认情况下,此属性为False。 如果此属性为true,则如果有文本类型的内容,并且没有设置`ContentCharset`属性,则内容类型中不包括任何字符集;这意味着字符集iso-8859-1用于消息输出。 - WriteRawMode属性影响实体正文(如果包含)。它控制请求正文的写入方式。默认情况下,此属性为False,并且InterSystems IRIS以请求标头中指定的编码写入正文。如果此属性为true,则InterSystems IRIS以原始模式写入正文(不执行字符集转换)。 - `ReadRawMode`属性控制如何读取响应正文。默认情况下,此属性为False,并且InterSystems IRIS假定正文在响应标头中指定的字符集中。如果此属性为true,InterSystems IRIS将以原始模式读取正文(不执行字符集转换)。 ## 使用代理服务器 可以通过代理服务器发送HTTP请求。要设置此设置,请指定HTTP请求的以下属性: - `ProxyServer`指定要使用的代理服务器的主机名。如果此属性不为空,则将HTTP请求定向到此计算机。 - `ProxyPort`指定代理服务器上要连接到的端口。 - `ProxyAuthorization`指定`Proxy-Authorization`标头,如果用户代理必须使用代理验证其自身,则必须设置该标头。对于该值,请使用正在请求的资源的用户代理所需的身份验证信息。 - `ProxyHTTPS`控制HTTP请求是针对HTTPS页面还是针对普通HTTP页面。如果未指定代理服务器,则忽略此属性。此属性将目标系统上的默认端口更改为代理端口443。 - `ProxyTunes`指定是否通过代理建立到目标HTTP服务器的隧道。如果为true,则请求使用HTTP CONNECT命令建立隧道。代理服务器的地址取自`ProxyServer`和`ProxyPort`属性。如果`ProxyHttps`为true,则隧道建立后,系统间IRIS将协商SSL连接。在这种情况下,由于隧道与目标系统建立直接连接,因此将忽略https属性。 ## 使用SSL进行连接 `%Net.HttpRequest`类支持SSL连接。要通过SSL发送请求,请执行以下操作: 1. 将`SSLConfiguration`属性设置为要使用的已激活SSL/TLS配置的名称。 2. 还要执行以下操作之一,具体取决于是否使用代理服务器: - 如果未使用代理服务器,请将`https`属性设置为true。 - 如果使用的是代理服务器,请将`ProxyHTTPS`属性设置为true。 在这种情况下,要使用到代理服务器本身的`SSL`连接,请将https属性设置为true。 请注意,当使用到给定服务器的`SSL`连接时,该服务器上的默认端口假定为443(HTTPS端口)。例如,如果没有使用代理服务器,并且https为true,则会将Default Port属性更改为443。 ### 服务器身份检查 默认情况下,当`%Net.HttpRequest`实例连接到SSL/TLS安全的Web服务器时,它会检查证书服务器名称是否与用于连接到服务器的`DNS`名称匹配。如果这些名称不匹配,则不允许连接。此默认行为可防止“中间人”攻击,在RFC 2818的3.1节中进行了描述;另请参阅RFC 2595的2.4节。 **若要禁用此检查,请将`SSLCheckServerIdentity`属性设置为0。** ## `HTTPVersion`、`Timeout`、`WriteTimeout`和`FollowRedirect`属性 `%Net.HttpRequest`还提供以下属性: `HTTPVersion`指定请求页面时使用的HTTP版本。默认值是`"HTTP/1.1"`。你也可以使用`“HTTP/1.0”`。 `Timeout`指定等待web服务器响应的时间,以秒为单位。 缺省值是30秒。 `WriteTimeout`指定等待Web服务器完成写入的时间(以秒为单位)。默认情况下,它将无限期等待。可接受的最小值为2秒。 `FollowRedirect`指定是否自动跟踪来自Web服务器的重定向请求(由300-399范围内的HTTP状态代码发出信号)。如果使用的是GET或HEAD,则默认值为TRUE;否则为FALSE。 ## 指定HTTP请求的默认值 可以为`%Net.HttpRequest`的所有属性指定默认值。 - 要指定适用于所有名称空间的默认值,请设置全局节 `^%SYS("HttpRequest","propname")`,其中`“PropName”`是属性的名称。 - 要为一个名称空间指定默认值,请转到该名称空间并设置节点`^SYS("HttpRequest","propname")` (`^%SYS`全局设置会影响整个安装,`^SYS`全局设置会影响当前命名空间。) 例如,要为所有名称空间指定默认代理服务器,请设置全局节`^%SYS("HttpRequest","ProxyServer")`
文章
Hao Ma · 一月 12, 2023

IRIS, Caché监控指导 - 诊断报告和性能报告

InterSystems公司的技术支持中心WRC(World Response Center)提供的服务包括故障报修,升级和数据迁移支持等等。当客户报告了系统故障或性能问题给WRC时, 会被要求收集以下的两份报告,以了解系统的运行情况和性能表现,它们是:***诊断报告(Diagnostic Report)和系统性能报告***。 ## 诊断报告(Diagnostic Report) 有关诊断报告,您需要知道: 1. **诊断报告是当前系统的运行状况的数据收集。** 2. **是给InterSystems技术支持工程师的,维护人员基本不需要读它。** 3. **当出现紧急故障需要重启系统时,先做一次诊断报告的收集,会对WRC在故障过后分析故障原因提供极大的便利。** #### 报告收集的步骤 进入管理门户页面,**“系统管理>诊断报告”(System Operation > Diagnostic Reports)**,点击**运行**。 - 报告收集通常**需要5-10分钟** - 执行开始后屏幕会出现提示:诊断报告在…时间运行.报告将储存在…目录中。成功后可以在“系统管理>任务管理器>任务历史“看到记录收集成功的记录。 - 在运行前,您可以选择报告存放的位置(Diectory for archived reports). - 如果不填写,**默认报告保存的目录是install-dir\mgr** ⚠️ :收集报告由内部用户irisuser执行,所以您选择的存放目录要有irisuser的读写权限。如果没有,点击“运行”时您并不能得到 提示错误,需要到“系统管理>任务管理器>任务历史“, 才能发现其实报告收集的任务没有执行。 - 如果有公网连接,可以配置邮件信息,报告会直接发送给WRC - 如果开设了WRC工单,请输入WRC工单号码 - 万一您已经无法登录管理门户,还是有紧急的故障要收集诊断报告,您需要[在Terminal执行命令收集诊断报告(附录1)][1]。 #### 报告的内容细节 诊断报告是一个HTML文件,名字是license中您的机构名称+时间, 比如这样:MyCompany202301051144.html 请记住2点: 1. 收集的数据分基本信息(Basic information)和高级信息(Advanced Information)。对于维护人员,基本信息可以在操作维护的各个页面上查看,没必要去读报告。而高级信息,不要求维护人员读懂或者分析内容。 具体内容如果如下,您可以选择跳过,或者从文档中了解更多的内容:[在线文档:Caché的诊断报告内容](https://docs.intersystems.com/ens201815/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_diagnostic#GCM_diagnostic_contents), [在线文档:IRIS的诊断报告内容](https://docs.intersystems.com/irisforhealth20211/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_diagnostic#GCM_diagnostic_contents)。 >报告的内容是系统当前的运行状态,主要包括: > >- 配置信息: > > 主要有服务器硬件信息,操作系统信息,许可证信息,实例的配置情况(CPF文件),数据库的配置,bin目录下的文件等等 > >- 当前系统的基本运行情况 > > - 数据库大小,占用的百分比 > - Journal的信息 > - 许可证的使用情况 > - 安全设置,审计(Audit)日志 > - 网络的状态。比如在Linux系统,其实是执行 `netstat -an` 的输出结果 > - 进程的状态 > - 内存的状态, cstat, core dump等等 > - GloStat ..., 不一一罗列 2. **cconsole.log**,或者**messages.log** 不包含在诊断报告中。通常情况下, 您需要把这个日志文件和诊断报告一起提交WRC #### 问题和回答 Q: 需要定期做诊断报告吗? A: 定期做系统健康检查吧,里面包括了诊断报告 Q: 要创建定时任务做诊断报告吗? A: 没必要。除非您要指定一个时间,比如要了解凌晨1AM的系统运行状况。 ## 性能报告(SystemPerformance Report) 有关性能报告,您需要了解: - 收集的数据包括操作系统的性能指标,Caché的设置,Caché性能指标等等。Caché性能指标大多数是每秒平均值。 - 报告收集 - Windows服务器:在Termial执行收集命令。 - Linux/Unix服务器:除了Terminal执行收集命令外,可以在管理门户设置定时任务(Task)执行。 > *为什么Windows服务器不能使用定时任务:* > > 性能报告的收集中会使用Windows系统的Perform.exe,也就是Windows系统性能监视程序。从用户管理门户设置Task, 或者使用当前非管理员权限的用户打开Terminal收集性能报告,会因权限不足导致内部调用Windows Perfom的失败,也就无法得倒操作系统的性能指标。 - 因为只是将系统默认收集的指标打包归档,所以它**对系统性能影响很小**。可以在任何时间执行。 - 即使没有故障要处理,定期的收集性能报告也是InterSystems推荐的。定期的报告保留了一个系统正常运行时的性能基线,便于今后的性能故障的原因分析,以及了解资源耗费情况的趋势。 如果操作中需要了解更多的内容,请参考在线文档:[Monitoring Performance Using ^SystemPerformance](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_systemperf)(for IRIS), [Monitoring Performance Using ^pButtons](https://docs.intersystems.com/ens201815/csp/docbook/Doc.View.cls?KEY=GCM_pbuttons)(for Caché)。 ### 在Terminal收集性能报告 #### Windows环境 1. 打开一个以管理员权限运行的Windows命令窗口。一般是找到CMD, 右键, “以管理员身份运行“。 2. 输入命令进入Caché或者IRIS终端。 - Caché: ` - IRIS : `iris console instanceName` 或者 `iris terminal instanceName` 3. 在%sys命名空间执行以下命令Routine: - Caché: `do ^pButtons` (见下面的例子) - IRIS : `do ^SystemPerfromance` ```zsh %SYS>do ^pButtons Current log directory: c:\intersystems\hsap\mgr\/intersystems\ Windows Perfmon data will be left in raw format. Available profiles: 1 12hours - 12 hour run sampling every 10 seconds 2 24hours - 24 hour run sampling every 10 seconds 3 30mins - 30 minute run sampling every 1 second 4 4hours - 4 hour run sampling every 5 seconds 5 8hours - 8 hour run sampling every 10 seconds 6 test - A 5 minute TEST run sampling every 30 seconds select profile number to run: 2 Collection of this sample data will be available in 86520 seconds. The runid for this data is 20200123_142501_24hours. %SYS>do Collect^pButtons Current Performance runs: 20200123_142501_24hours ready in 24 hours 1 minute 48 seconds nothing available to collect at the moment. ``` > `do Collect^pButtons`命令显示程序执行的状态。这是一个24小时的收集任务,显示的执行时间*“ready in 24 hours 1 minute 48 seconds”*比24小时略长,多出的2分钟用于^pButtons将整理日志并将数据转换为html格式。 #### Linux/Unix环境 进入iris terminal并执行收集命令`do ^pButtons`或者`do ^SystemPerformance` , 以下是在 ```bash $ iris session iris Node: af34ddc4655b, Instance: IRIS USER>zn "%sys" %SYS>do ^SystemPerformance Current log directory: /usr/irissys/mgr/ Available profiles: 1 12hours - 12 hour run sampling every 10 seconds 2 24hours - 24 hour run sampling every 10 seconds 3 30mins - 30 minute run sampling every 1 second 4 4hours - 4 hour run sampling every 5 seconds 5 8hours - 8 hour run sampling every 10 seconds 6 test - A 5 minute TEST run sampling every 30 seconds Select profile number to run: ``` ### 管理页面创建任务收集性能报告 对于Linux/Unix系统上安装的IRIS或者Caché, 到管理门户的“系统操作>任务管理器>新任务“,创建的新任务, ![image](/sites/default/files/inline/images/image-20230111132102826.png) 选项中,命名空间为“%SYS", 任务类型为”运行传统任务”(RunLegacyTask), 执行代码:: - Caché: `do run^pButtons(“ProfileName”)` - IRIS: `do run^SystemPerformance(“ProfileName”)` ProfileName也就是收集数据的时间长度, Profile定义数据采样的时间长度和频率,选项为:30mins, 4hours, 8hours, 12hours, 24hours, test。 - **24hours**: 最常用。任务执行的起始时间无所谓。如果设为零点,这样最后得到的数据图横轴是0点到24点,讨好细节控。 - **test**: 多用于24小时的收集工作前的预操作,查看5分钟的收集数据结果。 ### 其他有关报告收集的注意事项 1. 多个收集任务可并行。 比如为了分析某个性能问题, 客户可以从早上9点执行两个收集任务,一个4小时的任务收集早晨业务繁忙时段的数据,一个24小时的任务收集全天的数据。 2. 默认报告保存位置是***"/mgr"***文件夹。 一个24小时报告的尺寸通常在**10MB - 100MB**。如果要保留的报告很多,可以考虑执行命令修改保存目录(注意确保Caché具有该目录的写权限)。 `%SYS>do setlogdir^pButtons("/somewhere_with_lots_of_space/perflogs/")` 3. 还可以创建另一个定时任务,清除历史报告,只保留一段时间的。 4. 在一个长的报告收集过程中,可以使用`Preview^SystemPerformance`命令在[不中断收集的情况下,读取已经收集的性能报告的数据。如果需要, 请阅读[在线文档中生成报告的部分](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_systemperf#GCM_systemperf_produce)。 5. 如果可以要收集整个商业周期,比如一周或一个月的数据,需要[创建新性能采样profile(附录2)][2]。 6. 最后, 有一些内部的开关可以设置^pButtons采集更多的数据,比如硬盘访问的更详细的记录。通常这样的操作可能要消耗大量资源,请在WRC指导上使用。 ### 性能报告的内容 性能报告是一个html文件, 默认的文件名为服务器,实例名称, 时间的组合,比如bjse01_IRIS_20220628_103554_30mins.html。 内容主要为: - 配置, cpf文件,license等等 - 系统级别问题诊断,比如系统hang, 网络问题,性能问题等。(有兴趣可以去在线文档了解“cstat"或者“irisstat") - Caché,IRIS性能表现的采样, 比如Global的读写速度, Rdration等指标,有兴趣可以去在线文档了解“mgstat') - 操作系统的性能数据 - Windows Performance Monitor - Linux Info, ps, sar, vmstat... 具体内容请阅读: [InterSystems IRIS Performance Data Report for Microsoft Windows Platforms](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_systemperf#GCM_systemperf_reports_windows_) , [InterSystems IRIS Performance Data Report for Linux Platforms](https://docs.intersystems.com/iris20222/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_systemperf#GCM_systemperf_reports_linux) ### 性能报告内容的展现 性能报告是一个html文件。内容中的简单的数据,可以直观的在html中阅读, 但表格数据,比如cpu, 内存使用,IO, Global访问等等, 展现,或者说画图工具是有必要的。 **如果维护人员或用户想阅读性能报告**,可以考虑以下工具: [性能报告数据转csv](https://community.intersystems.com/post/extracting-pbuttons-data-csv-file-windows) : 这是一个windows PowerShell的程序, 方便使用EXCEL展现性能数据。 [YASPE](https://github.com/murrayo/yaspe) : 作者是Murrayo Oldfield,开源的工具,代码是python, 提供docker image下载。操作简单。数据可以生成图表,像下面的样子,而且可以zoom in/out。 ![example](https://github.com/murrayo/yaspe/raw/main/images/Glorefs_and_CPU_Utilisation_-_Sample_site_name_Monday_17_Jan_2022.png) WRC内部工具:如果您有了一个WRC工单,并且就当前问题提交了性能报告。您可以请你的技术支持提供一个报告中数据图表呈现。WRC问题有生成图表的工具,但仅供内部使用。 ## 附录 [1]: 在Terminal执行命令收集诊断报告 > 万一您已经无法登录管理门户,还是有紧急的故障要收集诊断报告,您需要在Terminal操作。 > > 这个操作命令叫**Buttons**. 据说,名字的出处是最初开发者任务收集报告应该简单的像“按一个按钮”,所以后面开发的性能报告,干脆就被称为**pButtons**, p是performance的字头。因为被使用的可能性太小,iris的文档中其实已经找不到Buttons的内容。下面的步骤只是简单的给您一个印象。如果有一天不幸您非要用它,WRC会详细的指导您。 > > ```sh > USER>zn "%sys" > %SYS>do ^Buttons > (以下步骤省略)... > ``` > > *执行^Buttons可以选择收集某一个命名空间的ensemble production的信息。如果有需要,请按WRC的要求操作。* [2]: 创建新性能采样profile > Profile定义收集数据的时长和频率, 比如24hours的profile是每10秒采样一次运行24小时。如果可以希望收集其他时间长度的数据,或者减小采样频率以减小结果文件的大小,可以考虑自己定制Profile。比如下面的my_24hours_30sec: > > ```sh > //创建24小时配置文件,30秒采样间隔。30sec*2880=1440mins=24hours > %SYS>write $$addprofile^pButtons("My_24hours_30sec","24 hours 30 sec interval",30,2880) > %SYS>do ^pButtons > Current log directory: /db/backup/benchout/pButtonsOut/ > Available profiles: > 1 12hours - 12 hour run sampling every 10 seconds > 2 24hours - 24 hour run sampling every 10 seconds > 3 30mins - 30 minute run sampling every 1 second > 4 4hours - 4 hour run sampling every 5 seconds > 5 8hours - 8 hour run sampling every 10 seconds > 6 My_24hours_30sec- 24 hours 30 sec interval > 7 test - A 5 minute TEST run sampling every 30 seconds > > select profile number to run: > ```
文章
Frank Ma · 六月 27, 2022

使用Python和仪表盘制作的一个欧洲水状况应用程序

比较不同的商业智能技术是非常有趣的。我很好奇它们在功能、开发工具、速度和可用性方面有什么不同。 在这个应用程序中,我选择了一个有欧洲各国水状况的数据集。这是一个开源的数据集,包含1991年到2017年的观测数据。 团队和我决定使用IRIS BI、Tableau、PowerBI和InterSystems Reports(由Logi Reports驱动)在这个BI数据集的基础上制作一个模型 对于前端,我们通过Embedded Python在PythonFlask中制作了一个网页界面。 顺便说一下,其结果可以在这个网页上看到:http://atscale.teccod.com:8080/ 你可以看看demo stand (演示台),因为从资源库部署一个容器可能需要多至20分钟的时间。大量的python包,后面会有更多的原因。 主页面 数据 事实上,数据似乎很小,期间只有17年 :) 因此,在现有的基础上,我想延续数据集,为此使用了一个神经网络。使用同样的嵌入式Python,使用了Tensorflow,这个包下载后占据了511MB,不要惊讶 实际上,这也是容器部署时间长的原因--为神经网络下载了很多包,相当多的相关包,安装时间很长。不过会有一篇关于神经网络和Integrated ML(一体化机器学习)的单独文章,我很快会发表。 我还要说的是,预测的结果被输入到同一个数据库,所以你可以通过BI工具看到数据集。但是预测只针对法国的一条河,请仔细看一下。因为我们只有足够的力量计算一件事。完整的预测会花很长的时间。 数据立方体 数据立方体是在IRIS中制作的,同时立方体也是在Adaptive Analytics(由AtScale驱动)中制作的。因此,IRIS的BI仪表盘是在IRIS上建立的,其余的工具(Logi、PowerBI、Tableau)从AtScale上获取数据。 仪表板 实际上商业智能系统是以多种形式呈现的。 这是在python中的Dash。 我们喜欢的IRIS BI InterSystems报告(由Logi报告提供)。 PowerBI Tableau 样例 完成 对于所介绍的所有BI系统,源文件都可以在资源库中找到。你可以看到报告和仪表盘是如何工作的,并在你未来的项目中使用它们。 通过它们,你可以直观地看到一个特定的系统是如何工作的,也可以了解一个特定的系统有哪些开发工具。 我们没时间来制作一个页面,让你可以输入各种参数和条件,使用神经网络的可能值进行计算。这里有一些先决条件,有一个实施神经网络的例子,以及在其帮助下所做的预测,这些都是在嵌入式Python中实现的。神经网络已被训练,启动脚本也是可用的,位于 https://github.com/teccod/water-conditions-Europe/blob/main/iris/src/PythonFlask/pages/ml/ml_run.py文件夹中。 谢谢你阅读这篇文章,我在等待评论和反馈。很快就会有一篇关于在嵌入式Python和IntegratedML(一体化机器学习)中比较神经网络的文章,我将把它附在这篇文章中。
文章
姚 鑫 · 四月 3, 2021

第十五章 使用管理门户SQL接口(二)

# 第十五章 使用管理门户SQL接口(二) # 过滤模式内容 Management Portal SQL界面的左侧允许查看模式(或匹配筛选器模式的多个模式)的内容 1. 通过单击SQL interface页面顶部的Switch选项,指定希望使用的名称空间。 这将显示可用名称空间的列表,可以从中进行选择。 2. 应用筛选器或从模式下拉列表中选择模式。 可以使用Filter字段通过输入搜索模式来筛选列表。 可以在一个模式或多个模式中筛选模式,或筛选表/视图/过程名(项)。 搜索模式由模式名、点(`.`)和项目名组成——每个名称由文字和通配符的某种组合组成。字面值不区分大小写。 通配符是: - 星号(`*`)表示0个或多个任意类型的字符。 - 下划线(`_`)表示任意类型的单个字符。 - 撇号(`'`)倒装前缀,意为“不”(除了)。 - 反斜杠(`\`)转义字符:`\_`表示字面上的下划线字符。 例如,`S*`返回所有以`S S*`开头的模式。 `Person`返回所有以`S. *`开头的模式中的所有Person项。 `Person*`返回所有模式中以`Person开头`的所有项。 可以使用逗号分隔的搜索模式列表来选择满足所列模式(或逻辑)中的任何一种的所有项。 例如,`* .Person * *`。 `Employee*`选择所有模式中的所有Person和Employee项。 若要应用筛选器搜索模式,请单击refresh按钮或按Tab键。 过滤器搜索模式将一直有效,直到显式地更改它。 过滤器字段右侧的`“x”`按钮清除搜索模式。 3. 从schema下拉列表中选择一个模式将覆盖并重置之前的任何筛选器搜索模式,选择单个模式。 指定筛选器搜索模式将覆盖之前的任何模式。 4. 可选地,使用下拉“应用到”列表来指定要列出的项目类别:表、视图、过程、缓存查询,或以上所有。 默认为`All`。 在“应用到”下拉列表中指定的任何类别都受到筛选器或模式的限制。 在“应用到”中没有指定的类别继续在名称空间中列出该类别类型的所有项。 5. 可选地,单击System复选框以包含系统项目(名称以`%`开头的项目)。 默认情况下不包含系统项。 6. 展开类别的列表,列出指定架构或指定筛选器搜索模式的项。 展开列表时,不包含项的任何类别都不会展开。 7. 单击展开列表中的项,在SQL界面的右侧显示其目录详细信息。 如果所选项目是表或过程,则Catalog Details类名信息提供到相应类参考文档的链接。 请注意,筛选器设置是用户自定义的,并保留以供该用户将来使用。 ## Browse选项卡 Browse选项卡提供了一种方便的方式,可以快速查看名称空间中的所有模式,或者名称空间中经过过滤的模式子集。 可以选择Show All Schemas或Show Schemas with Filter,这将应用在管理门户SQL界面左侧指定的过滤器。 通过单击模式名称标题,可以按字母升序或降序列出模式。 每个列出的模式都提供指向其关联表、视图、过程和查询(缓存的查询)列表的链接。 如果模式没有该类型的项,则在该模式列表列中显示一个连字符(而不是命名链接)。 这使能够快速获得关于模式内容的信息。 单击“表”、“视图”、“过程”或“查询”链接将显示有关这些项的基本信息的表。 通过单击表标题,可以按该列的值升序或降序对列表进行排序。 过程表总是包括区段过程,而不管管理门户SQL界面左侧的过程设置如何。 可以使用Catalog Details选项卡获得关于单个表、视图、过程和缓存查询的更多信息。 从Browse选项卡中选择表或视图不会激活该表的`Open Table`链接。 # 目录详情 管理门户提供每个表,视图,过程和缓存查询的目录详细信息。管理门户SQL界面的过滤架构内容(左侧)组件允许您选择单个项目以显示其目录详细信息。 ## 目录表的详细信息 每个表提供以下目录详细信息选项: - 表信息:表类型:表类型:无论是表,全局临时或系统表(仅在选择系统复选框时显示系统表),所有者名称,最后编译的时间戳,外部和读取的布尔值,类名称,范围大小,子表的名称和/或父表(如果相关)和一个或多个引用字段到其他表(如果相关),无论是使用`%storage.persistent`默认存储类,无论是支持位图指标, `ROWID`字段名称,`ROWID`基于(如果相关)的字段列表,以及表是否被分析。如果有一个显式分片键,它会显示分片键字段。 类名是在Intersystems类参考文档中的相应条目的链接。类名是通过删除标点字符,如标识符和类实体名称中所述从表名派生的唯一包。 只有当当前表中的某个字段对另一个表有一个或多个引用时,引用才会出现在表信息中。 这些对其他表的引用作为指向所引用表的表信息的链接列出。 Sharded:如果表是一个分片主表,那么表信息将显示分片本地类和表的名称,并链接到InterSystems类参考文档中相应的条目。 如果该表是一个碎片本地表,表信息将显示碎片主类和表的名称,并链接到InterSystems类参考文档中相应的条目。 只有选中“System”复选框时,才会显示“Shard-local”表。 该选项还为打开表时要加载的行数提供了一个可修改的值。 这将设置打开表中显示的最大行数。 可用范围从1到10,000; 默认值为100。 管理门户将一个超出可用范围的值修正为一个有效值:0修正为100; 一个小数四舍五入到下一个更大的整数; 大于10,000的数字更正为10,000。 - 字段:表中字段的列表,显示字段名,数据类型,列#,必需的,惟一的,排序,隐藏,MaxLen, MaxVal, MinVal,流,容器,xDBC类型,引用,版本列,选择性,离群值选择性,离群值和平均字段大小。 - 映射/索引:为表定义的索引列表,显示:索引名、SQL映射名、列、类型、块计数、映射继承和全局。 索引名称是索引属性名称,然后遵循属性命名约定;从SQL索引名称生成时,将删除SQL索引名称中的标点符号(例如下划线)。 SQL映射名称是索引的SQL名称。生成的SQL映射名称与约束名称相同,并遵循相同的命名约定(下面描述)。列指定为索引指定的字段或逗号分隔的字段列表;它可以指定index collation类型和full schinea.table.field参考,如下例所示:`$$sqlupper({sample.people.name})`。类型可以是以下之一:位图范围,数据/主,索引(标准索引),位图或`bitslice`索引以及唯一的约束。块计数包含计数和该计数的确定:由Class Author(定义)明确地设置,由可调组织(测量)计算,或由类编译器(估计)估计。如果映射继承?是的,map是从超类继承的。全局是包含索引数据的下标全局的名称。索引全局的命名约定在索引全局名称中描述。您可以向ZWRITE提供此全局名称以显示索引数据。 此选项还为每个索引提供重建索引的链接。 - 触发:为表显示的触发器列表显示:触发名称,时间事件,订单,代码。 - 约束:表格的字段列表,显示:约束名称,约束类型和约束数据(括号中列出的字段名称)。约束包括主键,外键和唯一约束。主键是定义,唯一;它仅列出一次。此选项列出约束名称的约束;使用显示组件字段的逗号分隔列表的约束数据列出了一次涉及多个字段的约束。约束类型可以是唯一的主键,隐式主键,外键或隐式外键。 还可以通过调用`Information_schema.constraint_column_usage`来列出约束。此列表按字段名称约束。以下示例返回字段的名称和所有唯一,主键,外键和`Check Constraints`的约束的名称: ```sql SELECT Column_Name,Constraint_Name FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE TABLE_SCHEMA='Sample' AND TABLE_NAME='Person' ``` ![image](/sites/default/files/inline/images/1_28.png) 如果该表定义为`%PublicraWID`,并且没有定义显式主键,则`RowID`字段列出了具有约束名称`RowidField_As_PKey`的`Contriced`主键的约束类型。 对于显式约束,约束名称是如下生成的: - 字段定义中指定的约束:例如,`fullname varchar(48)`唯一或`fullname varchar(48)`主键。字段的约束名称值是具有语法`tableName_ctype#`的生成值,其中ctype是唯一的,`pkey`或`fkey`,`#`是在表定义中指定的顺序分配给未命名约束的顺序整数。例如,如果`FullName`具有`MyTest`表中的第二个未命名的唯一约束(不包括ID字段),则`FullName`的生成约束名称将是`mytest_unique2`;如果`fullname`是`MyTest`表中指定的主键和第3个未命名约束(不包括ID字段),则`FullName`的生成约束名称将是`MyTest_pKey3`。 - 约束关键字命名约束子句:例如,约束`UFULLNAME`唯一(名字,`LastName`)或约束`Pkname`主键(`FullName`)),约束名称是指定的唯一约束名称。例如,`MyTest`表中的名字和`LastName`每个都将每个约束名称`UfullName`; `fullname`将具有约束名称`pkname`。 - 未命名约束子句:例如,唯一(名字,姓氏)或主键(`FullName`)。约束名称值是具有语法`tableNamectype#`的生成值,其中`ctype`是唯一的,`pkey`或`fkey`,`##`是在表定义中指定的顺序分配给未命名约束的顺序整数。例如,如果`FirstName`和`LastName`具有`MyTest`表中的第2个未命名的唯一约束(不包括ID字段),则`FirstName`和`LastName`的生成约束名称将是`MyTestunique2`;如果`FullName`是`MyTest`表中指定的主要键和第3个未命名的约束(不包括ID字段),则`FullName`的生成约束名称将是`MyTestPKEY3`。 (注意混合大写/小写,没有下划线。) 如果一个字段涉及多个唯一约束,则为每个约束名称单独列出。 - 缓存查询:表的缓存查询列表显示:例程名称,查询文本,创建时间,源,查询类型。 - 表的SQL语句:为此表生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 目录的视图详细信息 Management Portal SQL接口还提供视图,过程和缓存查询的目录详细信息: 为每个视图提供以下目录详细信息选项: - 查看信息:所有者名称,最后编译的时间戳。使用“编辑视图”链接并保存更改时,此时间戳更新。 定义为只读,视图是可更新的布尔值:如果仅读取的视图定义,则它们分别设置为1和0。否则,如果查看视图是从单个表定义的,它们被设置为0和1;如果视图由已加入的表定义,则它们设置为0和0。可以使用编辑视图链接更改此选项。 类名是唯一的包。通过删除标点字符,如标识符和类实体名称中所述,从视图名称派生的名称。 如果查看定义包含“使用”选项“子句,则仅列出选项。它可以是本地的或级联。您可以使用编辑视图链接更改此选项。 类类型是视图。它提供了编辑视图链接以编辑视图定义。 查看文本是用于定义视图的`SELECT`语句。可以使用编辑视图链接更改视图定义。 字段列表包括字段名称,数据类型,maxlen参数,maxval参数,minval参数,blob(`%stream.globalcharacter`或`%stream.globalbinary`字段),长度,精度和比例。 - 查看的SQL语句:为此视图生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 存储过程的目录详细信息 为每个过程提供以下目录详细信息: - 存储过程信息: 类名是一个唯一的包。通过将类型标识符( `‘func’, ‘meth’, ‘proc’, or ‘query’`)预定到类名(例如,SQL函数`MyProc`变为`FuncMyProc`)并删除标点符号字符,如标识符和类实体名称中所述。类文档是Intersystems类参考中相应条目的链接。过程类型(例如,函数)。方法或查询名称生成的类方法或类查询的名称;此名称在标识符和类实体名称中描述。运行过程链接提供交互方式的选项。 - 存储过程SQL语句:为此存储过程生成的SQL语句列表。与命名空间的SQL语句相同的信息。 ## 缓存查询的目录详细信息 缓存查询提供查询的全文,一个选项来显示查询执行计划,以及交互式执行缓存查询的选项。 # 向导 - 数据导入向导 - 运行向导将数据从文本文件导入Intersystems Iris类。 - 数据导出向导 - 运行向导将数据从Intersystems Iris类导出到文本文件中。 - 数据迁移向导 - 运行向导以从外部源迁移数据,并创建一个Intersystems Iris类定义来存储它。 - 链接表向导 - 运行向导,以链接到外部源中的表或视图,就像它是本机Intersystems Iris数据一样。 - 链接过程向导 - 运行向导,以链接到外部源中的过程。 # 操作 - 创建视图 - 显示一个页面以创建视图。使用此选项的说明提供了本书的“定义和使用视图”章节。 - 打印目录 - 允许打印有关表定义的完整信息。单击打印目录显示打印预览。通过单击此打印预览上的指数,触发器和/或约束,可以从目录打印输出中包含或排除此信息。 - Purege缓存查询 - 提供三种用于清除缓存查询的选项:清除当前命名空间的所有缓存查询,清除指定表的所有缓存查询,或者仅清除所选缓存的查询。 - 调谐表信息 - 对选定的表运行调谐表工具。这计算了每个表列对当前数据的选择性。选择性值1表示定义为唯一(因此具有所有唯一数据值)的列。选择性值为`1.0000%`表示未定义所有当前数据值是唯一值的唯一列。 `1.0000%`的百分比值更大,指示当前数据中该列的重复值的相对数量。通过使用这些选择性值,可以确定要定义的索引以及如何使用这些索引来优化性能。 - 调整架构中的所有表 - 运行调谐表工具,针对所属于当前命名空间中指定架构的所有表。 - 重建表索引 - 重建指定表的所有索引。 - 删除此项目 - 删除(删除)指定的表定义,查看定义,过程或缓存查询。必须具有适当的权限来执行此操作。除非表类定义包括[`DDLOWALLED`],否则否则不能在通过定义持久性类创建的表上使用删除。否则,操作失败了,使用`SQLCode -300`错误,其中包含类`“Schema.TableName”`的`%MSG DDL`。如果相应的持久性类具有子类(派生类),则不能在表格上使用删除;使用`%msg`类`'schema.tableName'`具有派生类`SQLCode -300`错误失败,因此无法通过DDL删除。 如果一个类被定义为链接表,则下降操作也会将链接表放在本地系统上,即使链接的表类未被定义为ddlowed。下降不会删除实际表此链接引用服务器上的引用。 - 导出所有语句 - 将所有SQL语句导出在当前命名空间中。 SQL语句以XML格式导出。可以选择导出到文件,或导出到浏览器显示页面。 - 导入语句 - 将SQL语句从XML文件导入当前命名空间。 # 打开表 如果在管理门户SQL接口的左侧选择表或视图,则会显示该表或视图的目录详细信息。页面顶部的打开表链接也变为活动状态。打开表显示表中的实际数据(或通过视图访问)。数据以显示格式显示。 默认情况下,将显示前100行数据;通过在“目录详细信息”选项卡信息中将表打开时,通过设置要加载的行数来修改此默认值。如果表格中的行数多于此行到加载值,则在数据显示的底部显示越多的数据...指示器。如果表格中的行较少,则要加载值的行数,则在数据显示的底部显示完整的指示符。 一列数据类型`%Stream.globalcharacter`将实际数据(最多100个字符)显示为字符串。超出前100个字符的附加数据由省略号(`...`)表示。 一列数据类型`%Stream.Globalbinary`显示为。 # 工具 System Explorer,SQL,Tools下拉列表提供对以下工具的访问。这些是系统资源管理器,工具,SQL性能工具的相同工具: - SQL运行时统计信息:用户界面生成指定查询的SQL运行时统计信息。 - 索引分析仪:用于收集指定架构的各种类型索引分析的用户界面。 - 替代表演计划:用户界面生成指定查询的备用显示计划。 - 生成报告以将SQL查询性能报告提交给Intersystems WRC(全球响应中心客户支持)。要使用此报告工具,必须先从WRC获取WRC跟踪号码。 - 导入报告以通过文件名导入现有WRC报告。仅用于Intersystems使用。 ![image](/sites/default/files/inline/images/2_17.png)
问题
sun yao · 十二月 27, 2022

能否从BP流程中提取出switch分支相关内容,通过解析代码或查看源表等相关操作?

如下图,系统表或代码中是否有相关方法可直接解析BP中的swith分支内容,实现接口的自动统计相关功能另:当前版本是否有已封装的页面,方便用户操作查看消息等功能 您好,对于BPL中的成分,由于其在代码中以XML记录,可以通过解析该类中xdata中的xml代码段,基于xml文本提取出switch标签中的内容进行解析可以获得其中的内容,可参考https://docs.intersystems.com/irisforhealth20222/csp/docbook/Doc.View.cls?KEY=GOBJ_xdata 但需要理解的是,基于静态代码分析得到的结果是理论上的分支,不一定能代表实际的业务运行情况,例如在代码有bug导致分支无效的情况等。而所有流经IRIS的消息都被持久化在消息标中,基于消息表通过SQL进行统计更能反映实际的业务运行状况。可参考:https://cn.community.intersystems.com/post/intersystems-%E6%95%B0%E6%8D%AE%E5%B9%B3%E5%8F%B0%E4%BA%92%E6%93%8D%E4%BD%9C%E5%8A%9F%E8%83%BD%E8%BF%90%E8%A1%8C%E7%BB%B4%E6%8A%A4%E7%AE%A1%E7%90%86%E5%9F%BA%E7%A1%80-%E4%BA%92%E6%93%8D%E4%BD%9C%E6%B6%88%E6%81%AF%E7%AE%A1%E7%90%86https://cn.community.intersystems.com/post/%E9%9B%86%E6%88%90%E4%BA%A7%E5%93%81%E7%9A%84%E4%B8%9A%E5%8A%A1%E8%A1%8C%E4%B8%BA%E7%9B%91%E6%8E%A7 另外,IRIS所有产品都带有查看消息的web界面,可以从portal中访问,也可以作为一个url被集成到用户自己的应用中去:
文章
Michael Lei · 八月 31, 2022

修改IRIS For Health 网页图标

背景Background 大多数网站都有一个 "Fav.ico "文件,用于设置网页的图标。大多数用户有多个环境,开发、测试和生产环境。通常情况下,你很难一眼就看出你在哪个环境中。如果能直观地通过图标看到你所处的版本和环境,可以提供更好的用户体验。在这个例子中,所有的实例都被命名为 "ENSEMBLE"。注意,这是在2022.1上使用的IRIS FOR HEALTH。 默认图标是 IR 在这篇文章中,我们将把标识改为类似于以下的内容: 图标文件 图标文件安装在你的安装文件夹csp/broker/portal中 创建一个名为Archive的文件夹放在该文件夹中 复制并粘贴ISC_IRIS_icon.ico到这个文件夹,对旧图标进行备份 使用一个图标编辑器。我使用了在线创建和编辑ICO文件| RedKetchup,因为它很容易使用,并且有简单的文本选项。 将.ico文件复制到你的本地文件,并打开它(Icon-> Open) 5. 采取铅笔工具。清除任何旧的字母(提示:改变铅笔大小可以更容易操作)。 6. Click test. Set colour. Play around with the font. DON'T FORGET TO PRESS APPLY 7. 保存图标. 8. 在一个全新安装的文件夹(DRIVELETTER:\InterSystems\HealthConnect\CSP\broker)中替换图标 9. 重新加载管理门户。. 注意你可能需要在chrome/edge上做一个硬刷新页面(通过按shift同时点击重新加载按钮)。 请注意,上述步骤在升级时可能不会生效,保存任何使用的图标,以便你可以再次更换标识。
文章
Frank Ma · 六月 13, 2022

Python和ObjectsScript中消息响应时间的对比测试

这是一个在InterSystems IRIS中用python和objectscript建立的对比测试。 测试目的是比较在python和objectscript中从BP到BO来回发送一千条请求/消息的速度。 更多信息,请访问 https://github.com/LucasEnard/benchmark-python-objectscript。 **重要提示** : 这里用的是python, graph objectscipt和objectscript从一个BP到一个BO来回发送1000条消息的时间,单位是秒。 字符串信息是由十个字符串变量组成。 对象信息由十个对象变量组成,每个对象都是它自己的int、float、str和List(str)。 | 消息字符串| 1000条消息来回的时间 (秒) | |------------------------|------------------| | Python BP | 1.8 | | BPL | 1.8 | | ObjectScript | 1.4 | | 消息对象| 1000条消息来回的时间 (秒) | |------------------------|------------------| | Python BP | 3.2 | | BPL | 2.1 | | ObjectScript | 1.8 | 行中函数的时间是列中函数的x倍 : | 消息字符串| Python | BPL | ObjectScript | |------------------------|------------|------------------------|------------------| | Python | 1 | 1 | 1.3 | | BPL | 1 | 1 | 1.3 | | ObjectScript | 0.76 | 0.76 | 1 | 例如,第一行告诉我们,Python字符串的时间是Objectscript图形字符串函数的1倍,是Objectscript字符串函数的1.3倍。 ( 利用第一个表格,我们可以验证我们的结果 : 1.3 * 1.4 = 1.8 1.3是第一行最后一列表格中的x,1.4s是本节第一个表格中看到的objectscript中的字符串信息的时间,1.8s实际上是python中的字符串信息的时间,我们可以通过寻找本节第一个表格或通过前面所示的微积分找到。) 行中的函数有列中函数X倍的时间: | Messages objects| Python | BPL | ObjectScript | |------------------------|------------|------------------------|------------------| | Python | 1 | 1.5 | 1.8 | | BPL | 0.66 | 1 | 1.2 | | ObjectScript | 0.55 | 0.83 | 1 |
公告
Michael Lei · 八月 13, 2022

[视频] 机器学习201--神经网络和图像识别

嗨,开发者们。 不要错过这个由InterSystems Healthcare副总裁@Donald.Woodlock主持的动手实践环节: ⏯ Machine Learning 201 - Neural Networks and Image Recognition 观看如何训练机器学习模型来做图像分类。几十年来,机器学习试图解决的最初的经典问题之一是如何在图片中区分狗和猫--这甚至是一个小孩子都能做到的事,但计算机却发现它非常困难。几十年后,这个问题被解决了,并为机器学习现在善于阅读放射学图像、识别人脸、为自动驾驶汽车识别物体类型、从卫星图像识别森林砍伐以及其他各种用例铺平了道路。我们将在这个实践环节中学习如何做到这一点。特别是,我们将解决识别手写数字的问题。我们将陆续建立更复杂的模型来提高这项任务的准确性,包括逻辑回归、前馈神经网络和卷积神经网络。 这是一个2小时的会议,通过虚拟会议的方式现场录制,有一些与会者参加。不要求有机器学习或python的经验,但最好不要讨厌编程。 你将需要一个Kaggle账户(http://www.kaggle.com)来跟上这个视频。该账户需要经过 "手机验证",以便使用Kaggle的GPU功能,这是其中一个练习所需要的。 作为本课的一部分,你将需要的链接是:https://www.kaggle.com/competitions/digit-recognizer笔记本的链接是:http://www.donwoodlock.com/ml201/25Jul2022/index.html 祝您愉快,敬请期待!
问题
Michael Lei · 四月 27, 2022

如何更改主键?

Hi, 请问如何更改表(有数据)上的主键?谢谢! 答: 如果数据已经存在,那么这是一项必须重视的任务,特别是如果存在继承或父/子关系,因为这将导致你的数据存储方案的改变。 最简单的方法是通过一个中间(临时)表来实现。 创建一个具有相同结构的新类,但有一个新的主键。使用SQL(不是合并命令)将数据从旧的类中移到它里面。删除旧类中的数据/索引,然后改变其中的主键。使用合并命令,将数据从新类移到旧类中。删除带有数据的新类。重建索引(如果有的话)。 几个有用的链接: MERGE 持久性对象和InterSystems IRIS SQL 持久性对象的介绍 如果仍然有问题,最好向WRC寻求帮助。 答: 如果数据已经存在,那么这是一项必须重视的任务,特别是如果存在继承或父/子关系,因为这将导致你的数据存储方案的改变。 最简单的方法是通过一个中间(临时)表来实现。 创建一个具有相同结构的新类,但有一个新的主键。使用SQL(不是合并命令)将数据从旧的类中移到它里面。删除旧类中的数据/索引,然后改变其中的主键。使用合并命令,将数据从新类移到旧类中。删除带有数据的新类。重建索引(如果有的话)。 几个有用的链接: MERGE
问题
lin qijun · 九月 13, 2021

怎么获取Caché的CDC数据?

1.Caché数据库有没有办法配置然后用sql读取数据库实时变化的数据,类似于mssql那样?我看了可以写类去读取global获取journal的值,但是怎么用sql读呢? 2.不行的话,那用什么方式可以读取到journal日志文件,并输出日志文件的内容? 先谢谢大家了!!! 请参考CDC 系列文章:https://cn.community.intersystems.com/post/cdc%E7%B3%BB%E5%88%97%E4%B9%8B%E4%B8%80-%EF%BC%9A%E4%BD%BF%E7%94%A8dejournal-filter%E5%9C%A8intersystems-iriscach%C3%A9%E4%B8%8A%E9%80%9A%E8%BF%87mirroring%E5%AE%9E%E7%8E%B0cdc%E5%8A%9F%E8%83%BD 这个试过了,配置dejournal没有问题,但是用$$$JRNNEWVAL(Address) 输入偏移量获取不到值的 注意文章中的提示: 1. $$$JRNNEWVAL(Address) 、$$$JRNOLDVAL(Address)`这2个宏定义在%syJrnRecord.inc文件里,因此需要将这个include文件加入ZCustom.MirrorDejournal类定义:Include %syJrnRecord 2.在InterSystems IRIS上修改并编译dejournal过滤器类后,需要重启异步镜像成员的Mirror,以使更改生效。 加了这个定义,并重启了的Mirror的,还是获取不到值的 使用的产品版本是什么?Dejournal filter是在Mirror report类型的异步镜像成员做的还是在shadow上做的?不同给的版本对应不同的处理方式。 同时还是建议将问题提到WRC:support@intersystems.com,他们会给予更详细的错误分析以及解决方案。 是在Mirror report类型的异步镜像成员上做的,版本是Cache for Windows (x86-64) 2016.2 (Build 736_0_16871U) Wed Dec 21 2016 09:38:49 EST版本 可以参考 %SYS.Journal.File.cls 这个类下的代码是如何使用$$$JRNNEWVAL(Address) 、$$$JRNOLDVAL(Address)的。
文章
Jingwei Wang · 十二月 30, 2021

用API描述文件创建REST服务

可以使用内嵌REST API用描述文件生成REST服务 请求消息如下: POST: http://[YourServer]/api/mgmnt/v2/INTEROP/cmAPI Body: API 描述文件,例如下面的Json文件Basic Authorization Username: 用户名 Basic Authorization Password: 密码 Content-Type Header: application/json ** 注意**:调用接口前,需要创建相应命名空间,本示例为INTEROP API 描述文件: { "swagger": "2.0", "info": { "description": "An API for coffee sales using InterSystems IRIS", "version": "1.0.0", "title": "Coffee Maker API", "license": { "name": "Apache 2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0.html" } }, "schemes": [ "https" ], "paths": { "/coffeemakers": { "post": { "description": "Returns all coffeemakers\n", "operationId": "QueryAll", "produces": [ "application/json" ], "parameters": [], "responses": { "200": { "description": "Success" }, "500": { "description": "Server error" } } } }, "/newcoffeemaker": { "post": { "description": "Add a new coffeemaker to the store. ID is autogenerated. Other info must be provided in the request body. Name and brand are required fields. Returns new coffeemaker\n", "operationId": "NewMaker", "produces": [ "application/json" ], "parameters": [ { "in": "body", "name": "body", "required": true, "schema": { "$ref": "#/definitions/CoffeeMaker" } } ], "responses": { "200": { "description": "Success" }, "400": { "description": "Invalid message body" }, "500": { "description": "Server error" } } } }, "/coffeemaker": { "post": { "description": "Retrieve existing coffeemaker given ID and data. Returns coffeemaker\n", "operationId": "QueryMaker", "produces": [ "application/json" ], "parameters": [ { "name": "id", "in": "query", "description": "CoffeemakerID", "required": true, "type": "integer" }, { "name": "prod", "in": "query", "required": false, "type": "boolean" } ], "responses": { "200": { "description": "Success" }, "404": { "description": "Coffeemaker not found" }, "500": { "description": "Server error" } } }, "put": { "description": "Update existing coffeemaker given ID and data. Returns updated coffeemaker\n", "operationId": "EditMaker", "produces": [ "application/json" ], "parameters": [ { "name": "id", "in": "query", "description": "CoffeemakerID", "required": true, "type": "integer" }, { "in": "body", "name": "body", "description": "coffeemaker info", "required": true, "schema": { "$ref": "#/definitions/CoffeeMaker" } }, { "name": "prod", "in": "query", "required": false, "type": "boolean" } ], "responses": { "200": { "description": "Success" }, "400": { "description": "Invalid message body" }, "404": { "description": "Coffeemaker not found" }, "500": { "description": "Server error" } } }, "delete": { "description": "Delete existing cofffeemaker given ID. Returns deleted coffeemaker\n", "operationId": "RemoveMaker", "produces": [ "application/json" ], "parameters": [ { "name": "id", "in": "query", "description": "CoffeemakerID", "required": true, "type": "integer" }, { "name": "prod", "in": "query", "required": false, "type": "boolean" } ], "responses": { "200": { "description": "Success" }, "404": { "description": "Coffeemaker not found" } } } } }, "definitions": { "CoffeeMaker": { "type": "object", "properties": { "Name": { "type": "string" }, "Brand": { "type": "string" }, "Price": { "type": "number" }, "NumCups": { "type": "integer" }, "Color": { "type": "string" }, "Img": { "type": "string" } } } } } 返回消息: { "msg": "New application cmAPI created" }