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

Web API performance issues with large dynamic XML

我创建了一个 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;
                }
            }
        }
    }

与其完全加载每个元素的字符串表示形式,不如考虑使用 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() 更简单,后者使用临时 XmlWriter 将输入流中的 XML 复制到输出 StringWriter。但是,如果不了解您在 ReadOuterXml().

下花费的时间,我无法预测改进是否会很大。