SQL Server - 更有效的散列算法?

时间:2016-07-12 15:43:40

标签: sql-server caching stored-procedures hash

我从远程SQL服务器本地缓存数据,并且需要知道远程数据何时更改,以便我可以更新缓存。远程数据没有修改日期列,我没有权限添加列或创建触发器,所以有很多选项对我来说是不对的。我当前的过程是计算远程表的校验和:

select checksum_agg(binary_checksum(*)) from remoteTable;

然后如果该值发生变化,我知道我需要更新缓存。这基本上有效,有两个缺点:

  1. 有许多变化导致校验和发生变化
  2. 我所知道的是"改变了一些事情"我需要将整个远程表复制到本地缓存中。
  3. 为了更高效和更正确,我想将我的流程升级到:

    1. 使用MD5哈希
    2. 返回多个哈希值,每个哈希值一个" chunk"输出表(在我的例子中,每10,000行),以便我只能更新" chunk"改变了
    3. 我创建了这个存储过程,它依赖于(显然未记录的)fn_repl_hash_binary函数:

      use dataBase;
      if exists (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'GetHash')
          drop procedure GetHash;
      create procedure GetHash
      as
      begin
      declare @j int, @x nvarchar(max), @b varbinary(max), @h nvarchar(40)
      set @j = 0
      IF OBJECT_ID('tempdb.dbo.##TempHashTable', 'U') IS NOT NULL
          DROP TABLE ##TempHashTable;
      create table ##TempHashTable(id int, xlen int, hash nvarchar(40))
      while (@j < 7)
      begin
         set @x = (select * from myTable where (id/10000) = @j for xml auto )
         set @b = convert(varbinary(max), @x)
         set @h = convert(char, sys.fn_repl_hash_binary(@b), 2)
         insert into ##TempHashTable(id, xlen, hash) values(@j, len(@x), @h)
         set @j = @j + 1
      end
      end;
      

      这是按预期工作的,唯一的缺点是它相当慢。校验整个表需要0.1秒(包括所有网络往返),而&#34; exec GetHash&#34;大约需要0.7秒。这不错,但我想知道我能不能做得更好。

      &#39; ID&#39;是myTable的主键,因此select应该是高效的,我所看到的是每个&#34; chunk&#34;生成的XML大约是2兆字节,其中大部分是重复的XML标记名字和尖括号。

      1. 有没有办法以比XML更不易读(但更有效)的格式输出myTable中的值?
      2. 我的存储过程中是否有其他明显的低效率会导致它变慢?
      3. 是的,此存储过程存在问题(例如,它仅适用于一个表,我假设该表总是包含少于70,000行)。一旦我对表演感到满意,我就会把所有的细节都放进去。

        我刚刚添加了一些时间码,这是我看到的:

        • 每个&#34;选择&#34;需要大约60毫秒
        • 计算每个散列大约需要25毫秒

0 个答案:

没有答案