我有这么简单的路线:
var records = db.MyDbTable.Where(x => x.SupplierId.HasValue).ToList();
执行需要一个小时。我在表中有272行。该表有一列NVARCHAR(MAX)
,里面有巨大的字符串。我该如何优化声明?之后在代码中我有一个foreach,它遍历记录并处理它们。
db中的select语句需要5分钟。
当我使用SQL profiler进行检查时,这是从C#转换的语句:
SELECT
[Extent1].[id] AS [id],
[Extent1].[xml] AS [xml],
[Extent1].[name] AS [name],
[Extent1].[create] AS [create],
[Extent1].[sale] AS [sale],
[Extent1].[SupplierId] AS [SupplierId],
[Extent1].[Success] AS [Success],
[Extent1].[IId] AS [IId]
FROM [dbo].[MyDbTable] AS [Extent1]
WHERE [Extent1].[SupplierId] IS NOT NULL
答案 0 :(得分:2)
正如OP在评论中所述,xml字段是必需的。然后正如D T
所说,你应该将它存储在单独的表中。此外,您可以在COMPRESSING
C#
之后添加此字段。我提供了一些使用BLToolKit
和EntityFramework
进行测试的统计信息。
我正在阅读包含70000
行的文本文件,每行包含70
个字符。那是5,039,998
的长度。以下是我想要分享的统计数据。我刚刚测试了35条没有压缩的记录,对于数据库中的每一行空间都需要大约9MB
。
如您所见,OutOfMemory Exception
,我没有深入研究。我只想看时间。我实际做的是,
在该表中插入数据时;在插入COMPRESS
字符串之前。该字段的数据类型为varbinary (MAX)
,我已经采取了。获取数据时;只有在你想要处理它时才能获取它。不要忘记DECOMPRESS
它。在SQL Server
中,需要0 seconds
来获取压缩记录。
以下是压缩和解压缩的代码。 Reference For The Code
public static void CopyTo(Stream src, Stream dest)
{
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
{
dest.Write(bytes, 0, cnt);
}
}
public static byte[] Zip(string str)
{
var bytes = Encoding.UTF8.GetBytes(str);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream())
{
using (var gs = new GZipStream(mso, CompressionMode.Compress))
{
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
public static string Unzip(byte[] bytes)
{
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream())
{
using (var gs = new GZipStream(msi, CompressionMode.Decompress))
{
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
希望对你有所帮助。
答案 1 :(得分:-3)
尝试将where where字段(SupplierId)的索引添加到数据库中,看看它是否有帮助。