我的一个程序查询数据库以查找给定元素的所有子元素及其所有子元素等,直到没有更多子元素并且我到达叶元素。数据库使用两列来存储我想要的信息。一列具有元素的id,另一列具有子元素的id。平均用例会导致树中包含500多个元素,完成所有查询需要30秒以上。我可以做些什么来优化查询并减少服务器上的瓶颈?
cursor = conn.cursor()
rootNode = Node(initialId)
nodeList.append(baseNode) # all nodes go into a list for debugging output
buildTree(baseNode, cursor)
def buildTree(self, node, cursor):
query = "SELECT childId FROM Pairs WHERE parentId=?"
cursor.execute(query, node.value)
results = cursor.fetchall()
for entry in results: # for each result returned, make a new node for each child
# and then query each child to see if it has children
if entry[0] is not None:
newNode = Node(entry[0], parent=node)
nodeList.append(newNode)
buildTree(newNode, cursor)
Node是一个短类,它充当数据结构来存储节点的id,它可能拥有的任何子节点以及父节点。我正在使用pyodbc
连接到SQL Server '08。
答案 0 :(得分:2)
首先,您需要以某种方式将查询逻辑与模型(树表示)分开。这将使您更灵活。
1)首先要考虑的是使用recursive query in SQL server一次获取所有需要的数据, 但是你需要小心,因为SQL服务器对递归调用有限制。
2)第二种是使用第一种方法或下一种方法编写存储过程。这将通过避免传输和查询解析成本来减少时间(但会防御性地增加代码支持共谋)
3)接下来是通过选择每个级别而不是每个项目来最小化数据库查询数量。像这样: 1.选择所有根节点 2.使用IN查询获取所有ID并查询所有子节点 3.重复2 ....
4)最后,如果你没有真正大量的记录,并且它们的数量不会显着增长,你可以只加载内存中的所有记录,然后构建你的树。您可以认为这会降低您的代码速度,但不会有数万分之一的记录。
任何情况下它确实依赖于您的数据大小和其他要求,例如,如果您的嵌套级别不大,则选项3将很好用,否则它将与您的代码相同。