优化对未知数据库的查询

本文关键字:查询 数据库 未知数 未知 优化 | 更新日期: 2023-09-27 18:08:53

第三方应用程序为每个项目创建一个数据库。所有数据库都具有相同的表和结构。新项目可以随时添加,所以我不能使用任何EF模式。

我现在做的是:

    private IEnumerable<Respondent> getListRespondentWithStatuts(string db)
    {
        return query("select * from " + db + ".dbo.respondent");
    }
    private List<Respondent> query(string sqlQuery)
    {
        using (var sqlConx = new SqlConnection(Settings.Default.ConnectionString))
        {
            sqlConx.Open();
            var cmd = new SqlCommand(sqlQuery, sqlConx);
            return transformReaderIntoRespondentList(cmd.ExecuteReader());
        }
    }
    private List<Respondent> transformReaderIntoRespondentList(SqlDataReader sqlDataReader)
    {
        var listeDesRépondants = new List<Respondent>();
        while (sqlDataReader.Read())
        {
            var respondent = new Respondent
            {
                CodeRépondant = (string)sqlDataReader["ResRespondent"],
                IsActive = (bool?)sqlDataReader["ResActive"],
                CodeRésultat = (string)sqlDataReader["ResCodeResult"],
                Téléphone = (string)sqlDataReader["Resphone"],
                IsUnContactFinal = (bool?)sqlDataReader["ResCompleted"]
            };
            listeDesRépondants.Add(respondent);
        }
        return listeDesRépondants;
    }

这工作得很好,但是速度很慢(每分钟20000条记录)。你有什么建议吗,什么策略应该更快?对于信息,真正慢的是transformReaderIntoRespondentList方法

谢谢! !

优化对未知数据库的查询

一般来说,任何SELECT * FROM都是不好的做法,但它也可能导致您不得不收回比实际需要更多的数据。转换仅对少数列进行操作,返回的列比所需的多吗?考虑替换为:

  private IEnumerable<Respondent> getListRespondentWithStatuts(string db)
  {
    return query("select ResRespondent, ResActive, ResCodeResult, Resphone, ResCompleted  from " + db + ".dbo.respondent");
  }

同时,防止sql注入攻击;为SQL查询连接字符串是非常危险的。

当从DataReader中提取数据时,我发现使用非命名查找效果最好:

  var respondent = new Respondent
  {
    CodeRépondant = sqlDataReader.GetString(0),
    IsActive = sqlDataReader.IsDBNull(1) ? (Boolean?)null : sqlDataReader.GetBoolean(1),
    CodeRésultat = sqlDataReader.GetString(2),
    Téléphone = sqlDataReader.GetString(3),
    IsUnContactFinal = sqlDataReader.IsDBNull(4) ? (Boolean?)null : sqlDataReader.GetBoolean(4)
  };

我已经很长时间没有明确测试性能差异了;但这曾经造成了显著的不同。顺序检查不必进行命名查找,也避免了装箱/拆箱值。

除此之外,没有更多的信息很难说……你需要全部20000张唱片吗?

运行一个包含300,000条记录的简单本地测试用例,并将加载所有数据的时间减少了近50%。我想这些结果会根据所检索的数据类型而有所不同;但它仍然会对总体执行时间产生影响。话虽如此,在我的环境中,我们谈论的是从650ms下降到刚刚超过300ms。

注意

如果respondent是一个视图,可能"真正慢"的是数据库建立结果集;尽管一旦有记录可用,数据读取器就会开始处理信息,但最终的瓶颈将是数据库本身和/或网络延迟。除了上述优化之外,您可以对代码做的事情不多,除非您可以索引视图/表以优化查询和或减少所需的信息。