繁体   English   中英

内部查询的sql优化

[英]sql optimisation for inner query

我有一个页面网站,每个页面可能属于几个类别。 用户被分配到类别,并且如果为页面分配了用户所属的类别,则他们可以看到该页面。

最初每个页面属于一个类别,我可以加入此表并检查权限,如此

where Sec.[level] > 0

既然页面可以有多个类别,我试图改变过滤掉结果的SP的where语句,虽然它有效但效率很低。 我获得了所有类别的最大权限,如果至少有一个大于零,则授予访问权限

WHERE 
        (

            (TLA.RecipientTypeID = 2 and (SELECT MAX(CAST(dbo.PersonHasPermission_forSection(CS.SectionID, @pViewersID, 1) AS tinyint))
                                          FROM CONTENT_SECTION CS
                                          WHERE CS.ContentID = tla.RecipientID) > 0
            )
            OR
            (TLA.RecipientTypeID <> 2 AND Sec.[level] > 0)
        )

或者因为只有页面有多个猫,其他类型的内容仍然只有一个。

我不知道这里是否有足够的信息,但任何优化提示将不胜感激。

根据您的WHERE语句,执行缓慢的主要原因是为内部子查询中的每一行调用一个函数。 我认为您不应该搜索MAX()并将其与0进行比较,在这种情况下您扫描所有表。 而不是尝试使用这样的EXISTS来查找只有一个权限> 0的记录 - 它应该是:

and EXISTS(SELECT * FROM CONTENT_SECTION CS 
             WHERE CS.ContentID = tla.RecipientID
             AND 
            (CAST(dbo.PersonHasPermission_forSection(CS.SectionID, @pViewersID, 1) 
                       AS tinyint)>0)
           ) 

在效率低下的情况下,通常需要重复调​​用函数。 有时通过消除对函数的多次调用可以获得很大的效率提升。 一种方法是使用临时表。 所以,这可能是值得探讨的事情。

但是,我想从您的特定SQL退一步,因为我认为数据建模和方法可能存在潜在问题。 按照你所描述的情况:

我有一个页面网站,每个页面可能属于几个类别。 用户被分配到类别,并且如果为页面分配了用户所属的类别,则他们可以看到该页面。

对于这种情况的最佳数据模型是三个“实体”表(类别,用户和页面),它们之间具有多对多关系; 多对多关系意味着要加入两个额外的表(UserCategory和PageCategory):

具有5个表的示例数据库结构

在这种情况下,要获取特定用户可以看到的所有页面的列表,您可以使用类似此示例的查询(这非常有效):

SELECT p.*
FROM UserCategory uc
  INNER JOIN PageCategory pc ON uc.CategoryID = pc.CategoryID
  INNER JOIN Page p ON pc.PageID = p.PageID
WHERE uc.UserID = @pViewersID

这是一个半笛卡尔式连接,但在这种情况下,这就是你想要的。 另请注意,为了使给定的示例查询具有最佳的SELECT效率,您还需要UserCategory.UserID上的索引。

最后,我删除了[Level]列,因为它似乎只用于真/假检查(“大于0”),这已经由UserCategory中的row-exists-or-not处理。 但是,如果您确实需要多个权限级别(超过0或1),请注意您还可以在UserCategory中包含[Level]列,并在示例查询中引用它以获得最低的额外成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM