2009-11-30 43 views
0

以下查询分别在一台标准机器上进行70分钟和1分钟的1百万条记录。可能的原因是什么?在SQL中发现性能差异很大(1小时到1分钟)。你能解释为什么吗?

查询[1点十分00秒]

SELECT * 
FROM cdc.fn_cdc_get_net_changes_dbo_PartitionTest(
    CASE WHEN sys.fn_cdc_increment_lsn(0x00)<sys.fn_cdc_get_min_lsn('dbo_PartitionTest')   
     THEN sys.fn_cdc_get_min_lsn('dbo_PartitionTest')   
     ELSE sys.fn_cdc_increment_lsn(0x00) END 
    , sys.fn_cdc_get_max_lsn() 
    , 'all with mask') 
WHERE __$operation <> 1 

修改的查询[0点01分10秒]

DECLARE @MinLSN binary(10) 
DECLARE @MaxLSN binary(10) 
SELECT @MaxLSN= sys.fn_cdc_get_max_lsn() 
SELECT @MinLSN=CASE WHEN sys.fn_cdc_increment_lsn(0x00)<sys.fn_cdc_get_min_lsn('dbo_PartitionTest')  
     THEN sys.fn_cdc_get_min_lsn('dbo_PartitionTest')   
     ELSE sys.fn_cdc_increment_lsn(0x00) END 

SELECT * 
FROM cdc.fn_cdc_get_net_changes_dbo_PartitionTest(
     @MinLSN, @MaxLSN, 'all with mask') WHERE __$operation <> 1 

[变形]

我试图重新创建具有相似功能的场景以查看是否针对每行评估参数。

CREATE FUNCTION Fn_Test(@a decimal)RETURNS TABLE 
AS 
RETURN 
(
    SELECT @a Parameter, Getdate() Dt, PartitionTest.* 
    FROM PartitionTest 
); 

SELECT * FROM Fn_Test(RAND(DATEPART(s,GETDATE()))) 

但是,对于在38秒内处理的百万条记录,我得到的'Parameter'列值相同。

回答

2

即使确定性标量函数每行至少被评估一次。如果相同的确定性标量函数在具有相同参数的同一“行”上出现多次,我相信只有这样才会评估一次 - 例如,在CASE WHEN fn_X(a, b, c) > 0 THEN fn_X(a, b, c) ELSE 0 END或类似的东西。

我觉得你的问题,RAND是因为你继续补种:RAND(中)与 相同的种子值

重复调用返回相同的 结果。

对于一个连接,如果RAND()是 称为具有指定种子值, RAND()的所有后续调用基于所接种的RAND() 呼叫 结果。例如,以下查询 将始终返回数字的相同序列 。

我已经采取了缓存标量函数的结果,正如你所指出的那样 - 甚至可以预先计算标量函数结果表并加入到它们中。最终必须做一些事情来使标量函数有效。没错,最好的选择是CLR - 显然这些表现远超SQL SQL UDF。不幸的是,我不能在我目前的环境中使用它们。

+0

但重新播种RAND()确保我们获得随机值的权利?通过提供第二个时间价值作为种子,我认为,我确保这一点。 – Faiz 2009-11-30 16:00:56

+0

您没有重寄RAND()。你为它传递一个单值,它返回一个单值,然后这个单值被传递给你的函数。 – 2009-11-30 17:20:47

+0

对不起,当我第一次阅读RAND()的用法时,我以为你是从tbl做SELECT fn(RAND(seed)),这当然和SELECT fn(a_number)FROM tbl是一样的,因为你用相同的价值。在任何情况下,关于标量函数行为的信息都是正确解释你的情况。 – 2009-11-30 17:43:30

6

在您的第一个查询中,您的fn_cdc_increment_lsnfn_cdc_get_min_lsn会针对每一行执行。在第二个例子中,只有一次。

+0

但它们只是该函数的参数。为什么它会针对每一行进行评估。当我第一次观察这个时,我也这么想。然后我试着用类似的函数测试这个案例[更新了问题的细节],但是它在两种情况下都在同一时间完成。 – Faiz 2009-11-30 12:36:20

+0

确实如此,但需要为输出中的每一行评估函数。 – Thorsten 2009-11-30 12:42:39

+0

任何人都可以请回答'为什么'? – Faiz 2009-11-30 17:14:01

相关问题