我维护一个存档数据库,它将历史数据存储在分区视图中。分区列是一个日期时间。视图下的每个表存储一个月的数据。
我们用datetime列上的check约束约束每个表上的事件。这允许优化器限制在事件日期时间列上搜索筛选查询的表。
check约束的名称是由Server生成的,因此很难通过查看它们的名称来知道它们做什么。
我希望约束名称有'CK_TableName_Partition‘形式。
我可以使用此查询生成重命名脚本,并从sql_text列复制数据。WHERE子句与check约束匹配,这些约束的名称看起来像是由Server生成的:
SELECT
checks.name AS check_name,
tabs.name AS table_name,
skemas.name AS schema_name,
cols.name AS column_name,
N'
EXECUTE sys.sp_rename
@objname = N''' + skemas.name + N'.' + checks.name + N''',
@newname = N''CK_' + tabs.name + N'_Partition'',
@objtype = ''OBJECT'';' AS sql_text
FROM sys.check_constraints AS checks
INNER JOIN sys.tables AS tabs ON
tabs.object_id = checks.parent_object_id
INNER JOIN sys.schemas AS skemas ON
skemas.schema_id = tabs.schema_id
INNER JOIN sys.columns AS cols ON
tabs.object_id = cols.object_id AND
cols.column_id = checks.parent_column_id
WHERE checks.name LIKE (
N'CK__' + SUBSTRING(tabs.name, 1, 9) +
N'__' + SUBSTRING(cols.name, 1, 5) +
N'__' + REPLACE(N'xxxxxxxx', N'x', N'[0-9A-F]') COLLATE Latin1_General_BIN2
)
ORDER BY table_name;输出如下所示:
check_name table_name schema_name column_name sql_text
CK__tbAcquisi__Acqui__5C4299A5 tbAcquisitions_201301 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__5C4299A5', @newname = N'CK_tbAcquisitions_201301_Partition', @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__76026BA8 tbAcquisitions_201302 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__76026BA8', @newname = N'CK_tbAcquisitions_201302_Partition', @objtype = 'OBJECT';
CK__tbAcquisi__Acqui__7D6E8346 tbAcquisitions_201303 Archive AcquisitionDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbAcquisi__Acqui__7D6E8346', @newname = N'CK_tbAcquisitions_201303_Partition', @objtype = 'OBJECT';
...
CK__tbRequest__Reque__60132A89 tbRequests_201301 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__60132A89', @newname = N'CK_tbRequests_201301_Partition', @objtype = 'OBJECT';
CK__tbRequest__Reque__1392CE8F tbRequests_201302 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__1392CE8F', @newname = N'CK_tbRequests_201302_Partition', @objtype = 'OBJECT';
CK__tbRequest__Reque__1AFEE62D tbRequests_201303 Archive RequestDT EXECUTE sys.sp_rename @objname = N'Archive.CK__tbRequest__Reque__1AFEE62D', @newname = N'CK_tbRequests_201303_Partition', @objtype = 'OBJECT';查询的结果似乎是正确的,服务器执行得很快。
但是执行计划的根节点有一个警告:
表达式中的类型转换(CONVERT_IMPLICIT(nvarchar(128),O.名字,0))可能影响查询计划选择中的"CardinalityEstimate“。
在这种情况下,这意味着什么?这样一个复杂的过滤器会使优化器感到困惑吗?我该担心什么吗?
发布于 2013-03-10 04:36:30
查询的结果似乎是正确的,服务器执行得很快。但是执行计划的根节点有一个警告:表达式中的类型转换(CONVERT_IMPLICIT(nvarchar(128),O.名字,0))可能会影响查询计划选择中的"CardinalityEstimate“,这在这个上下文中意味着什么?这样一个复杂的过滤器会使优化器感到困惑吗?我该担心什么吗?
警告是有信息的。如果查询执行缓慢,或者注意到基数估计不正确,则警告将为您提供信息,说明在何处查找可能的原因。
此警告由用于排序规则更改的隐式转换触发。如果使用排序规则是获得正确结果的最简单方法,那么可以随意保留它。或者,如果你更多地解释为什么需要它,有人会建议你。
顺便说一句,REPLACE可以替换为:
REPLICATE(N'[0-9A-F]', 8);(这个答案是对这个问题的评论的总结。)
https://dba.stackexchange.com/questions/36097
复制相似问题