使用左外连接和逗号分隔字符串优化查询

时间:2017-10-02 11:20:16

标签: tsql

我的数据库中有一些名为Items的表,它与ItemParents表有关系。一个项目可以有一个父项,一个父项可以有多个项目(类似于文件夹树结构)。我有一个名为ParentPermissions的第三个表,如果用户根据其角色可以查看父级,我在此表中拥有权限。如果他可以查看父母,他也可以查看该项目。在此表中,我们保存父节点和无法查看父节点的用户节点之间的关系。

例如,对于parentId = 1,如果此父级的表ParentPermissions中没有数据,则所有用户都可以看到它。如果parentPermissions中的parentId = 1的数据值为“5,6”,则角色为5和6的用户将无法看到此文件夹。角色4的用户可以看到它。

这是我的疑问:

SELECT count(*)
FROM Items item
INNER JOIN ItemParents parent ON parent.id = item.parentId
LEFT OUTER JOIN ParentPermissions permissions ON permissions.folderId = parent.id
WHERE permissions.view IS NULL OR (permissions.view != CONVERT(VARCHAR(5), @userRole + ',%') AND permissions.view != CONVERT(VARCHAR(5), @userRole) AND permissions.view != CONVERT(VARCHAR(5), '%,' +  @userRole))

我想以某种方式优化此查询,因为它被调用了很多次。我该怎么做?

1 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

  1. 创建仅包含当前用户的DENY文档的临时表

    CREATE TABLE #CurrentUserParentPermissions 
    (
        ParentID INT
    )
    
    INSERT INTO #CurrentUserParentPermissions (ParentID)
    SELECT *
    FROM ParentPermissions 
    WHERE (permissions.view != CONVERT(VARCHAR(5), @userRole + ',%') ....
    
  2. 然后使用此表

    应用左连接
    SELECT count(*)
    FROM Items item
    INNER JOIN ItemParents parent ON parent.id = item.parentId
    LEFT OUTER JOIN #CurrentUserParentPermissions permissions ON permissions.folderId = parent.id
    WHERE permissions.view IS NULL;