Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq Where比SQL Where快得多_C#_Sql Server_Linq - Fatal编程技术网

C# Linq Where比SQL Where快得多

C# Linq Where比SQL Where快得多,c#,sql-server,linq,C#,Sql Server,Linq,我是SQL新手,我很难理解为什么Where语句如此低效 关于数据库的一点背景知识。这是一个用于存储图标的SQL Compact Edition数据库。一个项目可以有多个图标,每个图标可以有多个路径,每个路径由几何体、颜色和不透明度组成。大约有2000个图标,大约有12000条路径 我试图创建一个只返回属于给定项目的图标的查询 SELECT Icons.Id, Icons.Name... etc FROM Icons INNER JOIN Projects ON Icons.FK_Project

我是SQL新手,我很难理解为什么Where语句如此低效

关于数据库的一点背景知识。这是一个用于存储图标的SQL Compact Edition数据库。一个项目可以有多个图标,每个图标可以有多个路径,每个路径由几何体、颜色和不透明度组成。大约有2000个图标,大约有12000条路径

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

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;
}
var iconTable=geticondafromdatabase()。其中(e=>e.Project==projectName);
私有列表geticondafromdatabase()
{
var getAlliconCommand=newsqlcecommand(//SQL以上);
返回returniconda(本地连接字符串,getAlliconCommand);
}
私有列表returniconda(字符串连接字符串,SqlCeCommand命令)
{
var icondatareturn=新列表();
使用(var连接=新SqlCeConnection(connectionString))
{
command.Connection=连接;
使用(命令)
{
尝试
{
connection.Open();
使用(SqlCeDataReader dataReader=command.ExecuteReader())
{
while(dataReader.Read())
{
icondatareturn.Add(新的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()),
颜色=数据读取器[“颜色”].ToString().Trim(),
Opacity=double.Parse(dataReader[“Opacity”].ToString().Trim()),
ispathcomact=bool.Parse(dataReader[“Compact”].ToString().Trim()),
ZOrder=int.Parse(dataReader[“ZOrder”].ToString().Trim())
});
}
}  
}
}
返回icondatareturn;
}

我不明白为什么返回每个图标,然后自己过滤掉结果会快得多。

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

另一方面,如果您没有索引,并且选择了行的一大个子集(例如2500行中的2000行),SQL Server将首先执行聚集索引扫描,然后再返回数据集的几乎所有行。此附加操作将占用大部分执行时间,并且不会显著减少结果集的大小


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

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

您显示的是sql,但您谈论的是linq。您可以显示真正的C代码吗?sql查询是实际执行的还是您认为它是什么?您在显示的代码中根本没有使用
iconTable
,但您使用的是
dataReader
,您没有反编译clared…很难理解你在做什么。你在下一次执行时清除了sql缓存吗?旁注:不要将所有内容都转换为字符串,然后返回到正确的类型,例如使用
double.Parse(dataReader[“Opacity”].ToString().Trim())
。而是将其存储为正确的类型,然后使用
dataReader.GetDouble(opacityIndex)
Icons.FK_projectd是否已编制索引?我刚刚运行了
在Icons上创建索引IconIdIndex(FK_projectd)
。它说它成功了,但对性能没有影响。如果SQL Server选择使用索引,索引可能会产生影响。如果它估计不会产生很大影响(例如,不太有选择性——例如第二段中的示例),它可能仍然会忽略它。这就是为什么根据执行计划进行DB性能调整很重要的原因。此外,您的查询中有多个
JOIN
s,因此您可能还需要一些其他索引。我将看看是否可以找到有关如何评估执行计划的教程。谢谢。