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()
.
下花费的时间,我无法预测改进是否会很大。
我创建了一个 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()
.