0

我想知道MySQL中有什么更好的。我有一个 SELECT 查询,它排除了与被禁止的用户 ID 关联的每个条目。

目前我在 WHERE 语句中有一个子查询子句,就像

AND (SELECT COUNT(*) 
     FROM TheBlackListTable 
     WHERE userID = userList.ID 
       AND blackListedID = :userID2 ) = 0

它将接受每个userID不存在的TheBlackListTable

在上一个请求中首先检索所有被禁止的 ID 并将上一个子句替换为是否会更快

AND creatorID NOT IN listOfBannedID
4

2 回答 2

2

LEFT JOIN / IS NULL并且NOT IN最快:

SELECT  *
FROM    mytable
WHERE   id NOT IN
        (
        SELECT  userId
        FROM    blacklist
        WHERE   blackListedID = :userID2
        )

或者

SELECT  m.*
FROM    mytable m
LEFT JOIN
        blacklist b
ON      b.userId = m.id
        AND b.blackListedID = :userID2
WHERE   b.userId IS NULL

NOT EXISTS产生相同的计划,但由于实施缺陷,效率略低:

SELECT  *
FROM    mytable
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    blacklist b
        WHERE   b.userId = m.id
                AND b.blacklistedId = :userID2
        )

所有这些查询在第一次匹配时停止blacklist(因此执行 a semi-join

COUNT(*)解决方案效率最低,因为MySQL将计算实际COUNT(*)而不是在第一次匹配时停止。

但是,如果您在UNIQUE上有一个索引(userId, blacklistedId),这不是什么大问题,因为无论如何不能有多个匹配项。

于 2012-06-04T10:46:16.660 回答
0

使用EXISTS子句检查不在黑名单中的用户。

示例查询

Select * from userList
where not exists( Select 1 from TheBlackListTable  where userID = userList.ID)

IN当存在固定值或值计数低时使用子句。

于 2012-06-04T10:43:51.147 回答