0

MySQLで何が優れているのか疑問に思いました。禁止されたuserIDに関連付けられたすべてのエントリを除外するSELECTクエリがあります。

現在、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(したがって、 を実行しますsemi-join)

最初の一致で停止するのではなく、実際の値を計算するCOUNT(*)ため、ソリューションは最も効率的ではありません。MySQLCOUNT(*)

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 に答える