第三章 优化表(二)

2021-04-20  本文已影响0人  Cache技术分享

第三章 优化表(二)

调整表计算值

调优表操作根据表中的代表性数据计算和设置表统计信息:

区段大小和行计数

从管理门户运行Tune Table工具时,ExtentSize是表中当前行的实际计数。默认情况下,GatherTableStats()方法还将实际行数用作ExtentSize。当表包含大量行时,最好对较少的行执行分析。可以使用SQL tune table命令并指定%SAMPLE_PERCENT来仅对总行的一定百分比执行分析。在针对包含大量行的表运行时,可以使用此选项来提高性能。此%SAMPLE_PERCENT值应该足够大,以便对代表性数据进行采样。如果ExtentSize<1000,则无论%SAMPLE_PERCENT值如何,TUNE TABLE都会分析所有行。

指定的ExtentSize可以小于或大于实际行数。但是,ExtentSize不应显著超过当前表数据中的实际行数。指定ExtentSize时,Tuning Table会为该数量的行外推行ID,然后执行采样。如果ExtentSize大大超过实际行数,则大多数采样的行ID将与实际行数据不对应。如果是这种情况,则无法计算字段选择性;相反,Tune Table将列出指定的ExtentSize作为计算的ExtentSize,并列出一个较小的数字作为SAMPLESIZE;Tune Table为这些不存在的计算值返回<Not Specified>

可以将ExtentSize设置为0。如果表从来不打算填充数据,但用于其他目的(如查询联接),则可能需要这样做。当将ExtentSize设置为0时,InterSystems IRIS会将每个字段的选择性设置为100%,并将每个字段的平均字段大小设置为0

选择性和异常值选择性

Tune Table以百分比计算每个属性(字段)值的选择性。
它通过对数据进行抽样来实现这一点,因此选择性总是一种估计,而不是一个精确的值。
选择性是基于所有属性值都是(或可能是)等可能的假设。
对于大多数数据来说,这是一个合理的假设。
例如,在一个普通人口表中,大多数数据值都是典型的:任何特定的出生日期都会出现在大约0.27%的数据中(365分之一);
大约一半是女性,一半是男性(50%)。
被定义为Unique的字段的选择性为1(不应与选择性为1.0000(1%)混淆)。
对于大多数性质,选择性百分比就足够了。

对于一些属性,Tune Table还计算离群值选择性。
这是单个属性值的百分比,与其他数据值相比,该属性值在示例中出现的频率更高。
只有当一个数据值的频率与其他数据值的频率存在显著差异时,调优表才会返回离群值选择性。
无论数据值的分布情况如何,Tune Table最多为表返回一个离群值。
如果选择了一个离群值,那么调优表将此值显示为离群值。
NULL表示为< NULL >

如果TuneTable返回异常值选择性,则正常选择性仍然是整个行集内每个非异常值数据值的百分比。例如,如果在1000个随机选择的值中检测到11个不同的值,其中一个是异常值,则选择性为1/11(9.09%):平均每个条目出现的几率为十一分之一。如果异常值选择性是80%,常规选择性是1%,那么除了异常值之外,还可以找到大约20((1-0.80)/0.01)个额外的非异常值。

如果优化表初始采样仅返回单个值,但附加采样返回多个不同的值,则这些采样结果会修改正常选择性。例如,990个值的初始随机采样仅检测一个值,但后续采样检测其他不同值的10个单个实例。在这种情况下,初始离群值会影响选择性值,该值现在被设置为1/1000(0.1%),因为10个非离群值中的每一个在1000个记录中只出现一次。

异常值选择性的最常见示例是允许NULL的属性。如果某个特性具有NULL的记录数大大超过该特性具有任何特定数据值的记录数,则NULL为异常值。以下是FavoriteColors字段的选择性和异常值选择性:

SELECTIVITY of FIELD FavoriteColors
   CURRENT =     1.8966%
   CALCULATED =  1.4405%
   CURRENT OUTLIER = 45.0000%, VALUE = <Null>
   CALCULATED OUTLIER = 39.5000%, VALUE = <Null> 

如果一个字段只包含一个不同的值(所有行都具有相同的值),则该字段的选择性为100%。选择性为100%的值不被视为异常值。调谐表通过采样数据来建立选择性和异常值选择值。为了确定这一点,优选表首先测试少量或几条记录,如果这些记录都具有相同的字段值,它将测试多达100,000条随机选择的记录,以支持非索引字段的所有值都相同的假设。只有在字段已编制索引,字段是索引的第一个字段,并且字段和索引具有相同的排序规则类型的情况下,优化表才能完全确定该字段的所有值是否相同。

要修改这些选择性、异常值选择性和异常值计算值,请从调谐表显示中选择单个字段。这会在显示屏右侧的详细信息区域中显示该字段的这些值。可以将选择性、异常值选择性和/或异常值修改为更适合预期完整数据集的值。

CALCSELECTIVITY参数与不计算选择性

在某些情况下,可能不希望优化表工具计算属性的选择性。要防止计算选择性,请将属性的CALCSELECTIVITY参数的值指定为0(默认值为1)。在Studio中,可以在“新建属性向导”的“属性参数”页上设置CALCSELECTIVITY,也可以在检查器中的属性参数列表中设置CALCSELECTIVITY(可能需要收缩并重新展开属性参数列表才能显示它)。

应该指定CALCSELECTIVITY=0的一种情况是,如果该字段未编制索引,则已知该字段在所有行中只包含一个值(选择性=100%)。

离群值的优化

默认情况下,查询优化器假定查询不会选择离群值。
例如,查询通常选择特定的字段值并从数据库返回少量记录,而不是返回大量记录,其中该字段值是离群值。
查询优化器总是使用选择性来构造查询计划,除非执行一些要求考虑离群选择性的操作。

根据选择离群值,可以执行以下几个操作来调整查询优化:

要确定当前设置,调用$SYSTEM.SQL.CurrentSettings()

通过指定%NORUNTIME restrict关键字,可以覆盖单个查询的RTPC
如果查询SELECT Name,HaveContactInfo FROM t1 WHERE HaveContactInfo=?
将导致RTPC处理,查询SELECT %NORUNTIME Name,HaveContactInfo FROM t1 WHERE HaveContactInfo=?
将覆盖RTPC,从而产生一个标准的查询计划。

通过指定注释选项/*#OPTIONS {"BiasAsOutlier":1} */,可以覆盖偏见查询作为单个查询的离群值。

“备注”列

管理门户优化表信息选项为每个字段显示一个备注列。此字段中的值是系统定义的,不可修改。它们包括以下内容:

注释列中未标识标识字段、ROWVERSION字段、序列字段或UNIQUEIDENTIFIER(GUID)字段。

平均字段大小

运行调谐表根据当前表格数据集计算所有非流字段的平均字段大小(以字符为单位)。这与AVG($length(Field))相同(除非另有说明),四舍五入到小数点后两位。可以更改各个字段的平均字段大小,以反映字段数据的预期平均大小。

如果特性/字段的特性参数CALCSELECTIVITY设置为0,则调谐表不会计算该特性/字段的平均字段大小。

可以通过从调谐表显示中选择单个字段来修改平均字段大小计算值。这将在显示屏右侧的详细信息区域中显示该字段的值。可以将“平均字段大小”修改为更适合预期的完整数据集的值。由于设置此值时优化表不执行验证,因此应确保该字段不是流字段,并且指定的值不大于最大字段大小(MaxLen)。

平均字段大小还显示在管理门户目录详细信息选项卡字段选项表中。必须已为字段选项表运行了调整表,才能显示平均字段大小值。

map BlockCount选项卡

调优表Map BlockCount选项卡显示SQL映射名称、BlockCount(作为正整数)和BlockCount的来源。
块计数的来源可以在类定义中定义、由类编译器估计或由TuneTable度量。
将类编译器估计的调优表更改运行到TuneTable测量;
它不影响在类定义中定义的值。

通过从调优表显示中选择单个SQL映射名称,可以修改BlockCount计算值。
这将在显示器右侧的详细信息区域中显示该地图名称的块计数。
可以将块计数修改为一个更适合预期的完整数据集的值。
因为在设置该值时,Tune Table不执行验证,所以应该确保块计数是一个有效值。
修改BlockCount会将BlockCount的来源更改为类定义中定义的。

导出和重新导入调优表统计信息

可以从一个表或一组表导出调优表统计信息,然后将这些调优表统计信息导入一个表或一组表。
以下是可能希望执行此导出/导入的三种情况。
(为简单起见,这些描述了从单个表导出/导入统计数据;
在实际使用中,通常会从多个相互关联的表中导出/导入统计数据):

可以使用$SYSTEM.SQL.Stats.Table.Export()方法将调优表统计信息导出到XML文件。此方法可以导出名称空间中一个、多个或所有表的优化表统计信息,如以下示例所示:

  DO $SYSTEM.SQL.Stats.Table.Export("C:\AllStats.xml")
  /* 导出当前命名空间中所有架构/表的TuneTable统计信息 */
  DO $SYSTEM.SQL.Stats.Table.Export("C:\SampleStats.xml","Sample")
  /*  导出Sample模式中所有表的可调统计信息 */
  DO $SYSTEM.SQL.Stats.Table.Export("C:\SamplePStats.xml","Sample","P*")
  /* 导出Sample模式中所有以字母“P”开头的表的可调统计信息 */
  DO $SYSTEM.SQL.Stats.Table.Export("C:\SamplePersonStats.xml","Sample","Person")
  /*  导出Sample的可调统计信息Person */

可以使用$SYSTEM.SQL.Stats.Table.Import()方法重新导入使用$SYSTEM.SQL.Stats.Table.Import()方法导出的调优表统计信息。

$SYSTEM.SQL.Stats.Table.Import()有一个KeepClassUpToDate boolean选项。
如果为真(并且update为真),$SYSTEM.SQL.Stats.Table.Import()将用新的EXTENTSIZE和选择性值更新类定义,但类定义将保持最新。
但是,在许多情况下,最好在调优了类表之后重新编译类,这样类定义中的查询就可以重新编译,SQL查询优化器就可以使用更新后的数据统计信息。
默认值为FALSE(0)。请注意,如果该类已部署,则类定义不会更新。

$SYSTEM.SQL.Stats.Table.Import()有一个ClearCurrentStats boolean选项。
如果为TRUE$SYSTEM.SQL.Stats.Table.Import()将在导入统计信息之前从现有表中清除所有先前的区段大小、选择性、块计数和其他调优表统计信息。
如果您想要完全清除导入文件中没有指定的那些表状态,而不是让它们在表的persistent类中定义,则可以使用此方法。
默认值是FALSE(0)

如果$SYSTEM.SQL.Stats.Table.Import()没有找到相应的表,它将跳过该表并继续导入文件中指定的下一个表。
如果找到了一个表,但是没有找到一些字段,那么这些字段将被跳过。

无法继承类存储定义中映射的BlockCountBlockCount只能出现在映射起源的类的存储定义中。如果映射源自超类,则$SYSTEM.SQL.Stats.Table.Import()仅设置投影表的BlockCount元数据,而不设置类存储BlockCount元数据。

上一篇下一篇

猜你喜欢

热点阅读