1

私はしばしば、次のような db クエリに直面します。

userX のすべてのエントリ (コメントなど) と、userX の友人のすべてのエントリを取得します

userX が自分の友人ではないと仮定すると、これは SQL (MySQL) でこれを行うための最良の方法です。

1. 2 つのクエリを作成し、後で PHP とマージする

a = SELECT *
    FROM comments
    WHERE user = X
b = SELECT c.*
    FROM comments c
    INNER JOIN relation r ON r.user2 = c.user
    WHERE r.user1 = X
merge(a, b)

それが私が通常行ってきたことです。それはかなりパフォーマンスが高いですが、ORDER BYまたはLIMITとして使用することはできません

2. IN および UNION を使用したサブクエリ

SELECT c.*
FROM comments
WHERE user IN (
    SELECT "X"
    UNION
    SELECT user2 FROM relation WHERE user1 = X
)

これは非常に遅いように見えるので、悪い考えですね。

3. その他の解決策は? 条件付き結合か何か...

4

3 に答える 3

0

これを行う 1 つの方法は、ユーザー テーブルからクエリを開始することです。関係テーブルと結合します。次に、条件付きの「ON」ステートメントを使用して、これに関するコメントを結合できます。このようにして、MySQL はインデックスを使用できます。

select c.* from users a
left outer join relation friend on a.id = friend.user1_id
join comments c on (c.user_id = a.id or c.user_id = friend.user2_id)
where a.id = 1
group by c.id;

これが実際の例です: http://sqlfiddle.com/#!2/da298/1

于 2013-11-07T13:47:44.977 に答える
0

なぜだめですか:

SELECT c.*
FROM comments
WHERE user = X OR user IN (
    SELECT user2 FROM relation WHERE user1 = X
)

それが遅い場合は、実行計画を確認する必要があります。索引がない可能性があります。

于 2013-11-07T13:28:24.153 に答える
0

あなたの#2には何の問題もありません。ほとんどの場合、必要なインデックスがありません。

学術的なケース スタディとして、同じ結果セットを返すさまざまな形式を次に示します。それぞれを で試して、EXPLAINどれが最もパフォーマンスが良いかを確認する必要があります (正しいインデックスが存在することを確認してください) (私は 3 番目に偏っています。INvsの MySQL パフォーマンスに関する記事を SO または Google で検索できますEXISTS) 。

UNION 結果 - これは #1 の改良版です。データは PHP ではなく MySQL で UNIONed のままです

SELECT *
FROM comments
WHERE user = X
UNION
SELECT c.*
FROM comments c
INNER JOIN relation r 
  ON r.user2 = c.user
WHERE r.user1 = X

あなたのオプション #2 -IN

SELECT c.*
FROM comments
WHERE user IN (
    SELECT "X"
    UNION
    SELECT user2 FROM relation WHERE user1 = X) 

存在する

一般に、IN複数のフィールドを関連付けることができるため、これよりもこちらを好みます

SELECT c.*
FROM comments AS c
WHERE c.user = X
   OR EXISTS(SELECT *
             FROM relation AS r
             WHERE r.user1 = X
                AND r.user2 = c.user)
于 2013-11-07T13:53:10.623 に答える