文章
姚 鑫 · 四月 28 阅读大约需 11 分钟

第八章 解释SQL查询计划(一)

第八章 解释SQL查询计划(一)

SQL语句

这个SQL语句列表为每个表提供了SQL查询和其他操作的记录,包括插入、更新和删除。
这些SQL语句链接到一个查询计划,该链接提供冻结该查询计划的选项。

系统为每个SQL DML操作创建一条SQL语句。
这提供了一个按表、视图或过程名称列出的SQL操作列表。
如果更改表定义,可以使用此SQL Statements列表来确定每个SQL操作的查询计划是否会受到此DDL更改的影响,以及/或是否需要修改某个SQL操作。
然后,可以:

  • 确定每个SQL操作使用哪个查询计划。
    可以决定使用反映对表定义所做更改的修改后的查询计划。
    或者可以冻结当前查询计划,保留在更改表定义之前生成的查询计划。
  • 根据对表定义所做的更改,确定是否对对该表执行SQL操作的例程进行代码更改。

注意:SQL语句是一个SQL例程列表,它们可能会受到表定义更改的影响。
它不应该用作表定义或表数据更改的历史记录。

创建SQL语句操作

下面的SQL操作会创建相应的SQL语句:

数据管理(DML)操作包括对表的查询、插入、更新和删除操作。
每个数据管理(DML)操作(动态SQL和嵌入式SQL)在执行时都会创建一个SQL语句。
- 动态SQL SELECT命令在准备查询时创建SQL语句。
此外,在管理门户缓存查询列表中创建了一个条目。
- 嵌入式SQL基于指针的SELECT命令在OPEN命令调用声明的查询时创建SQL语句。管理门户缓存查询列表中不会创建单独的条目。

如果查询引用多个表,则在名称空间的SQL语句中创建一条SQL语句,该语句列出表/视图/过程名列中的所有被引用表,并且对于每个单独的被引用表,该表的SQL语句列表都包含该查询的条目。

SQL语句是在第一次准备查询时创建的。如果多个客户端发出相同的查询,则只记录第一次准备。例如,如果JDBC发出一个查询,然后ODBC发出一个相同的查询,那么SQL语句索引将只有关于第一个JDBC客户端的信息,而不是关于ODBC客户端的信息。

大多数SQL语句都有关联的查询计划。
创建该查询计划时,将解冻该查询计划;
可以随后将该查询计划指定为冻结计划。
带有查询计划的SQL语句包括涉及SELECT操作的DML命令。
下面的“计划状态”部分列出了没有查询计划的SQL语句。

注意:SQL语句只列出SQL操作的最新版本。
除非冻结SQL语句,否则InterSystems IRIS®数据平台将用下一个版本替换它。
因此,在例程中重写和调用SQL代码将导致旧的SQL代码从SQL语句中消失。

其他SQL语句操作

下面的SQL命令执行更复杂的SQL语句操作:
- CREATE TRIGGER: 在定义触发器的表中,无论是在定义触发器还是在提取触发器时,都不会创建SQL语句。
但是,如果触发器对另一个表执行DML操作,那么定义触发器将在被触发器代码修改过的表中创建一个SQL语句。
Location指定在其中定义触发器的表。
在定义触发器时定义SQL语句;
删除触发器将删除SQL语句。
触发触发器不会创建SQL语句。
- CREATE VIEW 不创建SQL语句,因为没有编译任何内容。
它也不会更改源表的SQL语句的Plan Timestamp。
然而,为视图编译DML命令会为该视图创建一个SQL语句。

List SQL语句

本节介绍使用Management Portal界面列出SQL语句的详细信息。
也可以使用^rINDEXSQL全局返回SQL语句的索引列表。
注意,这个SQL语句List可能包含过时的(不再有效的)List

从Management Portal SQL界面可以列出如下SQL语句:
- SQL语句选项卡:此选项卡列出名称空间中的所有SQL语句,先按模式排序,然后按每个模式中的表名/视图名排序。此列表仅包括当前用户拥有权限的那些表/视图。如果SQL语句引用多个表,则表/视图/过程名列将按字母顺序列出所有被引用的表。
- 通过单击列标题,可以按表/视图/过程名、计划状态、位置、SQL语句文本或列表中的任何其他列对SQL语句列表进行排序。这些可排序列使能够快速查找,例如,所有冻结计划(计划状态)、所有缓存查询(位置)或最慢的查询(平均时间)。
- 可以使用此选项卡提供的Filter选项将列出的SQL语句缩小到指定的子集。
指定的筛选器字符串筛选SQL语句列表中的所有数据,最有用的是模式或模式。
表名、例程位置或SQL语句文本中找到的子字符串。
过滤字符串不区分大小写,但必须紧跟语句文本标点空格(name , age, not name,age)
如果查询引用了多个表,如果它选择了表/视图/过程名称列中的任何引用表,则Filter包括SQL语句。
过滤选项是用户自定义的。
- 最大行选项默认为1,000
最大值为10,000
最小值为10
要列出超过10,000条SQL语句,请使用INFORMATION_SCHEMA.STATEMENTS
页面大小和最大行选项是用户自定义的。
- Catalog Details选项卡:选择一个表并显示其Catalog详细信息。
此选项卡提供了一个表的SQL语句按钮,用于显示与该表关联的SQL语句。
注意,如果一个SQL语句引用了多个表,那么它将在表的SQL语句列表中列出每个被引用的表,但只有当前选择的表在表名列中列出。

通过单击列标题,可以根据列表的任何列对表的SQL语句列表进行排序。

可以使用SQLTableStatements()目录查询或INFORMATION_SCHEMA
语句,列出根据各种条件选择的SQL语句,如下面的查询SQL语句中所述。

列表列

SQL语句选项卡列出名称空间中的所有SQL语句。目录详细信息选项卡表的SQL语句按钮列出了所选表的SQL语句。这两个列表都包含以下列标题:
- #:列表行的顺序编号。这些数字与特定的SQL语句没有关联。
- 表/视图/过程名:限定的SQL表(或视图或过程)名:schema.name。如果SQL语句查询引用了多个表或视图,则所有这些表或视图都会在此处列出。
- 计划状态:请参阅下面的计划状态。
- 新计划:见“冻结计划”一章中不同的新计划。
- 自然查询:请参阅下面的语句详细信息部分。
- 计数:请参阅下面的性能统计数据。
- 平均计数:请参阅下面的性能统计数据。
- 总时间:请参阅下面的性能统计数据。
- 平均时间:请参阅下面的性能统计数据。
- 标准开发人员:请参阅下面的性能统计数据。
- Location(S):编译查询的位置,例程名称(对于嵌入式SQL)或缓存查询名称(对于动态SQL)。如果包名为%sqlcq,则SQL语句为缓存查询。
- SQL语句文本:规范化格式的SQL语句文本(截断为128个字符),可能与以下SQL语句文本中指定的命令文本不同。

计划状态

计划状态列出以下内容之一:
- 解冻Unfrozen:未冻结,可冻结。
- 解冻/平行Unfrozen/Parallel::未冻结,不能冻结。
- 冻结/显式Frozen/Explicit:由用户动作冻结,可以解冻。
- Frozen/Upgrade:被InterSystems IRIS版本升级冻结,可以解冻。
- blank:没有关联的查询计划:
- INSERT... VALUES() 命令创建的SQL语句没有关联的查询计划,因此无法解冻或冻结(计划状态列为空)。尽管此SQL命令不会生成查询计划,但它在SQL语句中的列表仍然很有用,因为它允许快速定位针对该表的所有SQL操作。例如,如果向表中添加一列,则可能需要找出该表的所有SQL插入的位置,以便可以更新这些命令以包括此新列。
- 基于游标的UPDATEDELETE命令没有关联的查询计划,因此不能解冻或冻结(“计划状态”列为空)。对已声明的游标执行OPEN命令会生成一条带有关联查询计划的SQL语句。使用该游标的嵌入式SQL语句(FETCH cursor, UPDATE...WHERE CURRENT OF cursor, DELETE...WHERE CURRENT OF cursor, and CLOSE cursor)不生成单独的SQL语句。即使基于游标的UPDATEDELETE不会产生查询计划,但SQL语句中列出的查询计划仍然很有用,因为它允许快速定位针对该表的所有SQL操作。

SQL语句文本

SQL语句文本通常不同于SQL命令,因为SQL语句生成规范化了字母和空格。
其他差异如下:

如果从Management Portal接口或SQL Shell接口发出查询,所得到的SQL语句与在SELECT语句前面加上DECLARE QRS CURSOR FOR(其中“QRS”可以是各种生成的游标名称)的查询不同。
这允许语句文本与Dynamic SQL缓存的查询相匹配。

如果SQL命令指定了一个非限定的表或视图名,那么生成的SQL语句将使用模式搜索路径(如果提供了DML)或默认模式名来提供模式。

SQL语句文本在1024个字符之后被截断。
要查看完整的SQL语句文本,请显示SQL语句详细信息。

一个SQL命令可能会产生多个SQL语句。
例如,如果一个查询引用一个视图,SQL Statements将显示两个语句文本,一个列在视图名称下,另一个列在基础表名称下。
冻结任意一条语句都会导致两个语句的Plan State为Frozen。

当通过xDBC准备SQL语句时,如果需要这些选项来生成语句索引散列,则SQL语句生成会向语句文本添加SQL Comment Options (# Options)。
如下面的例子所示:

DECLARE C CURSOR FOR SELECT * INTO :%col(1) , :%col(2) , :%col(3) , :%col(4) , :%col(5) FROM SAMPLE . COMPANY /*#OPTIONS {"xDBCIsoLevel":0} */ 

陈旧的SQL语句

删除与SQL语句关联的例程或类时,不会自动删除SQL语句列表。这种类型的SQL语句列表称为陈旧。由于访问此历史信息以及与SQL语句相关联的性能统计信息通常很有用,因此这些过时的条目将保留在管理门户SQL语句列表中。

可以使用Clean Stale(清除陈旧)按钮删除这些陈旧条目。清除陈旧删除关联例程或类(表)不再存在或不再包含SQL语句查询的所有非冻结SQL语句。清除陈旧不会删除冻结的SQL语句。

可以使用$SYSTEM.SQL.Statement.Clean()方法执行相同的清除陈旧操作。

如果删除与SQL语句关联的表(持久化类),则会修改表/视图/过程名称列,如下例所示:SAMPLE.MYTESTTABLE - Deleted??; ;已删除表的名称将转换为全部大写字母,并标记为“DELETED??”。或者,如果SQL语句引用了多个表:SAMPLE.MYTESTTABLE - Deleted?? Sample.Person.

  • 对于动态SQL查询,删除表时Location列为空,因为与该表关联的所有缓存查询都已自动清除。CLEAN STALE删除SQL语句。
  • 对于嵌入式SQL查询,Location列包含用于执行查询的例程的名称。当更改例程使其不再执行原始查询时,位置列为空。CLEAN STALE删除SQL语句。删除查询使用的表时,该表被标记“Deleted??”;Clean Stale不会删除SQL语句。

注:系统任务在所有名称空间中每小时自动运行一次,以清除任何可能过时或具有过时例程引用的SQL语句的索引。执行此操作是为了维护系统性能。此内部清理不会反映在管理门户SQL语句列表中。可以使用管理门户监视此每小时一次的清理或强制其立即执行。要查看此任务上次完成和下次调度的时间,请依次选择系统操作、任务管理器、任务调度,然后查看清理SQL语句索引任务。可以单击任务名称查看任务详细信息。在Task Details(任务详细信息)显示中,可以使用Run(运行)按钮强制立即执行任务。请注意,这些操作不会更改SQL语句清单;必须使用Clean Stale来更新SQL语句清单。

数据管理(DML)SQL语句

创建SQL语句的数据管理语言(DML)命令包括:INSERTUPDATEINSERTUPDATEDELETETRUNCATE TABLESELECTOPEN CURSOR(用于声明的基于游标的SELECT)。可以使用动态SQL或嵌入式SQL来调用DML命令。可以为表或视图调用DML命令,InterSystems IRIS将创建相应的SQL语句。

注意:系统在准备动态SQL或打开嵌入式SQL游标时(而不是在执行DML命令时)创建SQL语句。SQL语句时间戳记录此SQL代码调用的时间,而不是查询执行的时间(或是否)。因此,SQL语句可能表示从未实际执行的表数据更改。

准备动态SQL DML命令将创建相应的SQL语句。与此SQL语句关联的位置是缓存查询。动态SQL是在从管理门户SQL界面、SQL Shell界面执行SQL或从.txt文件导入时准备的。清除未冻结的缓存查询会将相应的SQL语句标记为清除陈旧删除。清除冻结的缓存查询会删除相应SQL语句的位置值。解冻SQL语句会将其标记为Clean Stale删除。

执行非游标嵌入式SQL数据管理语言(DML)命令将创建相应的SQL语句。每个嵌入式SQL DML命令都会创建相应的SQL语句。如果一个例程包含多个嵌入式SQL命令,则每个嵌入式SQL命令都会创建一个单独的SQL语句。(某些嵌入式SQL命令会创建多条SQL语句。)。SQL语句清单的Location列指定包含嵌入式SQL的例程。通过这种方式,SQL语句维护每个嵌入式SQL DML命令的记录。

打开基于游标的嵌入式SQL数据管理语言(DML)例程将创建带有查询计划的SQL语句。
关联的嵌入式SQL语句(FETCH游标、CLOSE游标)不会生成单独的SQL语句。
在FETCH游标之后,一个关联的UPDATE table WHERE CURRENT OF cursor 或DELETE FROM table WHERE CURRENT OF cursor会生成一个单独的SQL语句,但不会生成单独的Query Plan

插入文字值的INSERT命令将创建一个“计划状态”列为空的SQL语句。
由于该命令不会创建查询计划,因此无法冻结SQL语句。

select命令

调用查询将创建相应的SQL语句。
它可以是一个简单的SELECT操作,也可以是一个基于指针的SELECT/FETCH操作。
可以对表或视图发出查询。

  • 包含JOIN的查询为每个表创建相同的SQL语句。
    Location是清单中存储的每个表的相同查询。
    如SQL语句详细信息例程和关系部分所述,该语句使用以下关系列出所有表。
  • 包含选择项子查询的查询为每个表创建相同的SQL语句。
    Location是清单中存储的每个表的相同查询。
    如SQL语句详细信息例程和关系部分所述,该语句使用以下关系列出所有表。
  • 引用外部(链接)表的查询不能被冻结。
  • 一个包含FROM子句%PARALLEL关键字的查询可以创建多个SQL语句。
    你可以通过调用来显示这些生成的SQL语句:

image

这将显示包含原始查询的语句哈希的Statement列和包含生成的查询版本的语句哈希的ParentHash列。

%PARALLEL查询的SQL语句的计划状态为“未冻结/并行”,不能被冻结。

  • 不包含FROM子句(因此不引用任何表)的查询仍然创建SQL语句。
    例如:SELECT $LENGTH('this string')创建一个SQL语句,表列值%TSQL_sys.snf
00
1 0 0 15
Log in or sign up to continue