Aag*_*nor 1 c# sql sql-server performance stored-procedures
我使用ANTS分析器来识别我的C#应用程序中的剩余瓶颈:SQL Server存储过程.我正在使用SQL Server 2008.这里的任何人都可以帮助我提高性能,或者指出我可以做些什么来使其更好或更高效?
首先,这是程序:
PROCEDURE [dbo].[readerSimilarity]
-- Add the parameters for the stored procedure here
@id int,
@type int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF (@type=1) --by Article
SELECT id1, id2, similarity_byArticle FROM similarity WHERE (id1 = @id OR id2 = @id)
AND similarity_byArticle != 0
ELSE IF (@type=2) --by Parent
SELECT id1, id2, similarity_byParent FROM similarity WHERE (id1 = @id OR id2 = @id)
AND similarity_byParent != 0
ELSE IF (@type=3) --by Child
SELECT id1, id2, similarity_byChild FROM similarity WHERE (id1 = @id OR id2 = @id)
AND similarity_byChild != 0
ELSE IF (@type=4) --combined
SELECT id1, id2, similarity_combined FROM similarity WHERE (id1 = @id OR id2 = @id)
AND similarity_combined != 0
END
Run Code Online (Sandbox Code Playgroud)
表' similarity'由两个ids(id1和id2)和一些存储double值的列组成.约束是这样的id1 < id2.
Column Data ----- ---- ID1 PK, Indexed ID2 PK, Indexed The table contains 28.5 million entries.
存储过程的工作是让所有具有参数的行id任一id1或id2.此外,type-parameter指定的列不能为零.
对于不同的存储过程被多次调用ids.虽然只~1.6 ms接听每次通话,但总结起来,称它为17,000次.
处理器只运行25%,这似乎是因为应用程序正在等待程序调用返回.
你有没有办法加快速度?
C# Code Snippetprivate HashSet<NodeClustering> AddNeighbourNodes(int id)
{
HashSet<NodeClustering> resultSet = new HashSet<NodeClustering>();
HashSet<nodeConnection> simSet = _graphDataLoader.LoadEdgesOfNode(id);
foreach (nodeConnection s in simSet)
{
int connectedId = s.id1;
if (connectedId == id)
connectedId = s.id2;
// if the corresponding node doesn't exist yet, add it to the graph
if (!_setNodes.ContainsKey(connectedId))
{
NodeClustering nodeToAdd = CreateNode(connectedId);
GraphAddOuter(nodeToAdd);
ChangeWeightIntoCluster(nodeToAdd.id, s.weight);
_bFlowOuter += s.weight;
resultSet.Add(nodeToAdd);
}
}
// the nodes in the result set have been added
to the outernodes -> add to the outernodes count
_setNodes[id].countEdges2Outside += resultSet.Count;
return resultSet;
}
Run Code Online (Sandbox Code Playgroud)
每次将新id添加到群集时都会调用此方法.它获取所有连接的节点id(它们是连接的,当数据库中带有id1=id或带有条目时id2=id)
_graphDataLoader.LoadEdgesOfNode(id);
Run Code Online (Sandbox Code Playgroud)
然后它会检查所有已连接的ids以及它们是否尚未加载:
if (!_setNodes.ContainsKey(connectedId))
Run Code Online (Sandbox Code Playgroud)
它载入它们:
CreateNode(connectedId);
Run Code Online (Sandbox Code Playgroud)
方法:
_graphDataLoader.LoadEdgesOfNode(id);
Run Code Online (Sandbox Code Playgroud)
再次被召唤,这一次与connectedId.
我需要这个来获得新节点与已经在集合中的那些节点的所有连接.
我可能会收集ids我需要添加的所有节点,并使用一个id列表只调用我的存储过程一次.
我可以通过像这样的东西一次加载连接的ids连接
SELECT id1, id2, similarity_byArticle FROM similarity WHERE
(id1 = @id OR id2 = @id OR
id1 IN (SELECT id1 FROM similarity WHERE id2 = @id) OR
id2 IN (SELECT id1 FROM similarity WHERE id2 = @id) OR
id1 IN (SELECT id2 FROM similarity WHERE id1 = @id) OR
id2 IN (SELECT id2 FROM similarity WHERE id1 = @id))
AND similarity_byArticle != 0
Run Code Online (Sandbox Code Playgroud)
但是后来我会得到比我需要的更多的条目,因为我也会为已经加载的节点获取它们(从我的测试中它将占到调用的大约75%).
List<int>作为SP参数吗?如果它快速运行,您的问题可能在于重复调用该过程的数量.有没有办法可以修改存储过程和代码,以便在一次调用中返回应用程序所需的所有结果?
优化在不到2毫秒内运行的查询可能不是一项富有成效的工作.我怀疑你能通过查询调整来削减超过几分之一毫秒的时间.