大型动态XML的Web API性能问题

时间:2015-03-11 17:55:49

标签: c# xml performance asp.net-web-api

我创建了一个WebAPI sql接口,以便开发用户可以通过RESTful接口动态查询数据库。它对于小型查询来说速度很快,但是当较大的查询发挥作用时,会出现严重的滞后问题,尤其是在进行多个同时呼叫时。我对此进行了性能分析,绝大多数处理都是在线完成的:

var xe = reader.ReadOuterXml();

客户端期待XML文本字符串所以我试图只做一个ExecuteReader,但结果以2033字节块的形式返回,这似乎比较慢,这是不幸的,因为在SQL Server Management中运行此查询Studio(带有' For XML Auto')几乎是即时的。

我正在测试16MB XML响应,但他们的响应超过150MB - 200MB。

如何优化此功能以更好地处理这些大型响应?代码如下:

public XElement AdHockSelect([FromBody] XElement valueElement, string connectionStringName, string database)
{
    try
    {
        string rawConnectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
        string sqlconnectionstring = string.Format(rawConnectionString, database);
        using (SqlConnection sqlConnection = new SqlConnection(sqlconnectionstring))
        {
            string[] sqlComandTexts = valueElement.Value.Trim().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            string sqlQueryText = "";

            foreach (var sqlComandText in sqlComandTexts)
            {
                sqlQueryText += sqlComandText + "  for xml auto;";
            }

            sqlConnection.Open();
            SqlCommand sqlCommand = new SqlCommand(sqlQueryText, sqlConnection);

            using (XmlReader reader = sqlCommand.ExecuteXmlReader())
            {
                XElement xd = new XElement(new XElement("Response"));

                if (reader.EOF)
                {
                    return XElement.Parse("<Response/>");
                }
                else
                {
                    while (!reader.EOF)
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            var xe = reader.ReadOuterXml();
                            xd.Add(XElement.Parse(xe));
                        }
                        else
                        {
                            reader.Read();
                        }
                    }
                    return xd;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

不要完全加载每个元素的字符串表示,而是考虑使用XNode.ReadFrom()直接将XML流式传输到新的XElement

                if (reader.NodeType == XmlNodeType.Element)
                {
                    var element = XNode.ReadFrom(reader) as XElement;
                    if (element != null)
                        xd.Add(element);
                }
                else
                {
                    reader.Read();
                }

这比使用ReadOuterXml()更简单,{{3}}使用临时XmlWriter将输入流中的XML复制到输出StringWriter。但是,如果不了解ReadOuterXml()下花费的时间,我无法预测改善是否会有所改善。