【发布时间】:2016-12-08 18:35:10
【问题描述】:
我是 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;
}
我不明白返回每个图标然后自己过滤掉结果怎么会这么快。
【问题讨论】:
-
你显示 sql 但你在谈论 LINQ。你能展示真正的C#代码吗? sql查询是实际执行的还是你认为的?
-
您在显示的代码中根本没有使用
iconTable,但是您使用的是dataReader,您还没有声明......很难遵循您的内容正在做。 -
你在下次执行时清除了 sql 缓存吗?
-
旁注:不要将所有内容都转换为字符串,然后再转换回正确的类型,例如与
double.Parse(dataReader["Opacity"].ToString().Trim())。而是将其存储为正确的类型,然后使用dataReader.GetDouble(opacityIndex) -
Icons.FK_ProjectId 是否已编入索引?
标签: c# sql-server linq