Linq哪里比SQL快得多

时间:2016-11-29 08:48:59

标签: c# sql-server linq

我是SQL的新手,我很难理解为什么这个Where语句效率低下。

数据库的一些背景知识。它是一个SQL Compact Edition数据库,用于存储图标。项目可以有多个图标,每个图标可以有多个路径,每个路径都由几何图形,颜色和不透明度构成。大约有2000个图标,大约有12000个路径。

enter image description here

我试图创建一个只返回属于给定项目的图标的查询

SELECT Icons.Id, Icons.Name... etc FROM Icons
INNER JOIN Projects ON Icons.FK_ProjectId = Projects.Id 
INNER JOIN IconDetails ON Icons.Id = IconDetails.FK_IconId
INNER JOIN Paths ON IconDetails.FK_PathId = Paths.Id
INNER JOIN Colours ON IconDetails.FK_ColourId = Colours.Id
WHERE (Icons.FK_ProjectId = 5)

这需要大约2.8秒才能完成。但是,如果我删除底部Where语句,它只需要约0.3秒。然后,我可以使用C#Linq选择它们属于我想要的项目的所有图标。

var iconTable = GetIconDataFromDatabase().Where(e => e.Project == projectName);


private List<IconData> GetIconDataFromDatabase()
{
    var getAllIconsCommand = new SqlCeCommand( // SQL Above);

    return ReturnIconData(LOCAL_CONNECTION_STRING, getAllIconsCommand);
}

private List<IconData> ReturnIconData(string connectionString, SqlCeCommand command)
{
    var IconDataToReturn = new List<IconData>();

    using (var connection = new SqlCeConnection(connectionString))
    {
        command.Connection = connection;

        using (command)
        {
            try
            {
                connection.Open();

                 using (SqlCeDataReader dataReader = command.ExecuteReader())
                 {
                     while (dataReader.Read())
                     {
                         IconDataToReturn.Add(new IconData
                         {
                             Id = int.Parse(dataReader["Id"].ToString().Trim()),
                             Project = dataReader["ProjectName"].ToString().Trim(),
                             Name = dataReader["Name"].ToString().Trim(),
                             Geometry = Geometry.Parse(dataReader["Geometry"].ToString().Trim()),
                             Colour = dataReader["Colour"].ToString().Trim(),
                             Opacity = double.Parse(dataReader["Opacity"].ToString().Trim()),
                             IsPathCompact = bool.Parse(dataReader["Compact"].ToString().Trim()),
                             ZOrder = int.Parse(dataReader["ZOrder"].ToString().Trim())
                       });

                    }
                }  
            }
        }
    return IconDataToReturn;
}

我不明白如何更快地返回每个图标,然后自己过滤掉结果。

2 个答案:

答案 0 :(得分:3)

对此没有一般性的答案。您的性能值将在很大程度上取决于数据库大小和使用的索引等因素。如果你的表中有很多行,并且Icons.FK_ProjectId上有一个非常有选择性的索引(例如你只选择了10万行),我怀疑加载所有行并选择更快使用LINQ,因为DB可以使用索引进行搜索操作(快速)并且只返回一小部分行(也很快)。

另一方面,如果你没有索引并且你选择了一大部分行(例如2500行中的2000个),那么SQL Server首先必须执行聚簇索引扫描,然后才会回显几乎所有的行。数据集。此附加操作将占用执行时间的最佳部分,并且不会显着减小结果集的大小。

您应该做的是比较执行计划与否在哪里,看看您是否可以优化查询。在数据库级别进行调优通常更适合在客户端进行调优。

答案 1 :(得分:0)

本身不是答案,但可能是对未来任何人都有用的解决方案。我在SQLite中实现了完全相同的功能,并且能够在0.03秒内恢复数据,而无需自己执行任何linq。