【问题标题】:Case Sensitivity when querying SQL Server 2005 from .NET using OleDB使用 OleDB 从 .NET 查询 SQL Server 2005 时区分大小写
【发布时间】:2010-09-14 01:58:15
【问题描述】:

我有一个从 .NET 应用程序到 SQL Server 数据库的查询,它似乎需要很长时间才能完成(5 分钟以上)。我在 c# 中创建了一个测试应用程序来尝试查看这么长时间的谈话内容(查询应该很快返回)。

当我通过添加元素来重构查询以查看哪个部分花费了这么长时间时,我最终几乎逐字地重构了查询,其中唯一的区别是原始查询中的空格和大小写差异。这种差异会在大约 100 毫秒内返回结果。

以前有人见过吗?我想知道我们的服务器(因为同事有同样的问题)或我们的计算机上是否有服务关闭。

在此先感谢您提供任何帮助。

下面的代码示例(末尾查询的第一行中的差异(fk_source vs. fk _Source):

//Original
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >=  CONVERT(datetime,'01-01-2008',105)  and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105)  and s.c_id = '27038dbb19ed93db011a315297df3b7a'", dbConn);

//Rebuilt
    OleDbCommand comm = new OleDbCommand("select min(ctc.serial_no) as MIN_INTERVAL from countstypecode ctc, source s, countstype ct, counts c where ct.value_id=c.value_id and s.c_id=ct.fk_Source and " +
      "ct.timeinterval=ctc.typename and ct.timeinterval in ('15min','1h','1day') and c.time_stamp >= CONVERT(datetime,'01-01-2008',105) and c.time_stamp < " +
      "CONVERT(datetime,'01-01-2009',105) and s.c_id='27038dbb19ed93db011a315297df3b7a'", dbConn);

【问题讨论】:

    标签: c# .net sql-server oledb case-sensitive


    【解决方案1】:

    由于您使用的是 SQL Server 2005,您是否尝试过使用 SqlCommand 对象而不是 OleDbCommand 对象?

    【讨论】:

    • 如果您使用的是 SQL Server AND .Net,这很有意义。
    • 是的,但它的意思是可以和其他数据库互换,我们只是在SQL server中注意到了这种行为,所以我专门询问了它。
    【解决方案2】:

    我没有发现您的查询存在会影响性能的差异 - 运行之间的缓存或索引/统计数据变化会怎样?由于统计信息或索引更改,执行计划可能已更改。

    关于大小写:如果数据库设置为区分大小写,则大小写可能很重要,但是对于在区分大小写的数据库中运行的两个查询,必须有以两种格式命名的列 - 查询解析器将服从这种情况 - 它不会导致性能差异。

    【讨论】:

      【解决方案3】:

      首先,您是否 100% 确定查询出错了?检查 sql server 中的跟踪配置文件,看看它在数据库中占用了多长时间。

      其次,您是否获得了相同数量的结果。在 sql server 中默认大小写应该无关紧要,但它可以设置不同。

      【讨论】:

        【解决方案4】:

        如果我的查询耗时“5 分钟以上”,我不会担心匹配字符串大小写所需的 100 毫秒。

        【讨论】:

        • 2个查询的差异,1个5+分钟返回,1个100毫秒返回
        【解决方案5】:

        感谢大家的回答,我会依次回复:

        1) Russ,我同意 SQLConnection 会更好,但不幸的是我无法设置连接类型。我刚刚创建了一个小应用程序来测试这个查询,但查询是在一个更大的应用程序中动态创建的。

        2) gbjbaanb,我认为这不是服务器问题,因为我可以同时从管理工作室运行两个查询,这似乎只是在 .net(1.1 和 2.0)中通过 oledb 运行时出现问题.我们对其运行了探查器,跟踪文件确认以这种方式调用完成查询需要 5 多分钟。

        3) Joel Coehoorn,同意,但我真正想在这里说明的是“为什么”,因为现在我们不知道这个问题有多大以及它在哪里。

        4)Cade Roux,差异是非常可复制的,所以我认为这不是索引更改或缓存的问题,因为我已经以相同的结果背靠背运行测试并且它们花费了大约相同的时间要运行的 SQL Server。

        【讨论】:

        • 您已经隔离在这两个查询之间(没有其他因素)并且每次都获得这种性能差异?我会向 Microsoft 开一张票 - 这些查询之间的差异不足以证明性能差异。
        【解决方案6】:

        我怀疑这是一个过程缓存问题。存储过程的一个好处是计划是为您存储的,这可以加快速度。不幸的是,有可能在缓存中得到一个错误的计划(即使使用动态查询)。

        只是为了好玩,我检查了我的过程缓存,运行了一个临时查询,再次检查,然后我用不同的大写字母运行了相同的查询,我惊讶地发现过程计数更高。

        试试这个....

        连接到 SQL Server Management Studio。

        DBCC MemoryStatus
        
        Select Columns... From TABLES.... Where....
        
        dbcc MemoryStatus
        
        Select Columns... From tables.... Where....
        
        dbcc MemoryStatus
        

        我想你会发现 TotalProcs 会随着语句的变化而变化(即使唯一的变化是区分大小写的)。

        更新您的统计信息可能会有所帮助。这是一个相当缓慢的运行过程,因此您可能希望在缓慢的时间内运行它。

        【讨论】:

          【解决方案7】:

          感谢 G Mastros 提供最完整的答案,尽管回想起来统计数据的更新是 Cade 建议的。不过,G Mastos 的解决方案更适合我的 SQL Server 经验水平。

          感谢大家的帮助!

          我将研究为什么这种看似无辜的差异会产生如此大的后果

          【讨论】:

            猜你喜欢
            • 2012-04-17
            • 2011-03-24
            • 2015-07-23
            • 1970-01-01
            • 1970-01-01
            • 2010-11-27
            • 1970-01-01
            • 1970-01-01
            • 2016-01-17
            相关资源
            最近更新 更多