简单表格中的语句需要一个小时

时间:2018-04-26 06:41:07

标签: c# sql-server entity-framework linq query-performance

我有这么简单的路线:

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

2 个答案:

答案 0 :(得分:2)

正如OP在评论中所述,xml字段是必需的。然后正如D T所说,你应该将它存储在单独的表中。此外,您可以在COMPRESSING C#之后添加此字段。我提供了一些使用BLToolKitEntityFramework进行测试的统计信息。

我正在阅读包含70000行的文本文件,每行包含70个字符。那是5,039,998的长度。以下是我想要分享的统计数据。我刚刚测试了35条没有压缩的记录,对于数据库中的每一行空间都需要大约9MB

enter image description here

如您所见,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)的索引添加到数据库中,看看它是否有帮助。