sql-server – XPath fn:sql server中的数据导致表达式中的类型转换可能影响查询计划选择中的“CardinalityEstimate”

我有一个xml变量,其中包含一组我想在表中查找的ID.在查询时我尝试了几个版本,但以下(从我的测试中)似乎是最快的:

declare @idsxml as xml (IdSchemaColelction) = '<root><Id>505766</Id><Id>458073</Id><Id>460689</Id><Id>464050</Id></root>'

SELECT * FROM entity
WHERE @idsXml.exist('/root/Id[data(.)=sql:column("id")]') = 1

的问题是,查询计划具有以下警告“在表达类型转换(CONVERT_IMPLICIT(SQL_VARIANT,CONVERT_IMPLICIT(数字(38,10),[Xmltest的].[DBO].[实体].[ID],0),0 ))可能影响查询计划选择中的“CardinalityEstimate”“

我创建了一个xml架构,将Id的文本定义为一个整数,所以我希望数据(.)= sql:column(“id”)是整数之间的比较,但这个警告暗示不然.

在这种情况下删除此警告的正确方法是什么?这会对性能产生影响吗?

表定义和模式定义:

CREATE XML SCHEMA COLLECTION IdSchemaColelction AS  '
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" >
  <xs:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" 
             schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd"/>
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="Id" type="sqltypes:int" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
'
go

create table entity ( id int not null  primary key)
最佳答案
我不认为,你的方法是最好的或最快的…

以下是一些比较它们的方法:

用于测试

create table test ( id int not null  primary key);
insert into test VALUES(100),(200),(505766),(300),(400),(500),(458073),(600),(700),(464050),(800),(900),(1000)
GO

这是你的ID列表

declare @idsxml as xml = '<root><Id>505766</Id><Id>458073</Id><Id>460689</Id><Id>464050</Id></root>'

– 这是你的方法.它会一遍又一遍地解析XML
– .data()肯定 – 不是读取类型安全数据进行比较的最佳方法……

SELECT test.id
FROM test
WHERE @idsXml.exist('/root/Id[data(.)=sql:column("id")]') = 1;

– 这是完全相同的方法,但使用更快的XQuery

SELECT test.id
FROM test
WHERE @idsXml.exist('/root/Id[text()=sql:column("id")]') = 1;

– 这有点慢……可能是因为存在隐式类型转换……

SELECT test.id
FROM test
WHERE @idsXml.exist('/root[Id=sql:column("id")]') = 1;

– 使用更大的列表,在INNER JOIN中使用派生表可能更好

WITH DerivedTable AS
(
    SELECT i.value('.','int') AS id
    FROM @idsxml.nodes('root/Id') AS A(i)
)
SELECT test.id
FROM test 
INNER JOIN DerivedTable AS dt ON test.id=dt.id;

– 并且有一个大的列表,您甚至可以考虑索引声明的表(在内存中读取最后的量子速度)

DECLARE @tbl TABLE(id INT NOT NULL PRIMARY KEY) --PK only, if your XML never contains a value twice!
INSERT INTO @tbl
SELECT i.value('.','int') AS id
FROM @idsxml.nodes('root/Id') AS A(i);

SELECT test.id
FROM test 
INNER JOIN @tbl AS tbl ON test.id=tbl.id;

GO

DROP TABLE test;

转载注明原文:sql-server – XPath fn:sql server中的数据导致表达式中的类型转换可能影响查询计划选择中的“CardinalityEstimate” - 代码日志