6

私はMySQLクエリの初心者なので、これは明白な答えのある質問だと確信しています。

しかし、私はこれら2つのクエリを見ていました。それらは異なる結果セットを返しますか?並べ替えプロセスの開始方法が異なることは理解していますが、最初のクエリの方が少し効率的で、同じ結果が返されると思いますか?

クエリ1:HAVING、次にAND

SELECT user_id   
FROM forum_posts  
GROUP BY user_id 
    HAVING COUNT(id) >= 100   
    AND user_id NOT IN (SELECT user_id FROM banned_users)

クエリ2:WHERE、次にHAVING

SELECT user_id   
FROM forum_posts 
WHERE user_id NOT IN(SELECT user_id FROM banned_users) 
GROUP BY user_id 
    HAVING COUNT(id) >= 100   
4

5 に答える 5

1

実際には、最初のクエリは効率が低下します(HAVING後に適用されWHEREます)。
アップデート

クエリがどのように実行されるかを示すいくつかの擬似コード([非常に]簡略化されたバージョン)。
最初のクエリ:
1。2 SELECT user_id FROM forum_posts
. 3.SELECT user_id FROM banned_user
グループ化、カウントなど
。4.レコードが2番目に表示される場合は、最初の結果セットからレコードを除外します 。

2番目のクエリ1.2.3
. SELECT user_id FROM forum_posts
2SELECT user_id FROM banned_user
番目の結果セットにレコードが表示されている場合は、最初の結果セットからレコードを除外します
。4.グループ、カウントなど。

ステップ1、2の順序は重要ではありません。mysqlは、より適切と思われるものを選択できます。重要な違いはステップ3、4にあります。後に適用されGROUP BYます。グループ化は通常、結合よりもコストがかかるため(この場合、レコードを結合操作と見なすことができます)、グループ化する必要のあるレコードが少ないほど、パフォーマンスが向上します。

于 2011-06-23T16:34:36.660 に答える
1

2つのクエリで同じ結果が表示され、どちらかがより効率的なさまざまな意見が表示されるという回答はすでにあります。

私の意見では、オプティマイザーが2つのクエリに対して異なる計画を実行した場合にのみ、効率(速度)に違いが生じます。最新のMySQLバージョンでは、オプティマイザーはどちらのクエリでも同じプランを見つけるのに十分賢いので、まったく違いはありませんが、もちろん、EXPLAINを使用して実行プランをテストして確認するか、一部のクエリに対して2つのクエリを実行できます。テストテーブル。

安全のために、とにかく2番目のバージョンを使用します。


それを追加させてください:

  • COUNT(*)COUNT(notNullableField)通常、MySQLよりも効率的です。それが将来のMySQLバージョンで修正されるまで、COUNT(*)該当する場合は使用してください。

したがって、次のものも使用できます。

SELECT user_id   
FROM forum_posts 
WHERE user_id NOT IN
  ( SELECT user_id FROM banned_users ) 
GROUP BY user_id 
HAVING COUNT(*) >= 100   
  • NOT IN適用する前に同じ(to)サブ結果を達成する他の方法もありますGROUP BY

使用LEFT JOIN / NULL

SELECT fp.user_id   
FROM forum_posts AS fp
  LEFT JOIN banned_users AS bu
    ON bu.user_id = fp.user_id
WHERE bu.user_id IS NULL 
GROUP BY fp.user_id 
HAVING COUNT(*) >= 100  

使用NOT EXISTS

SELECT fp.user_id   
FROM forum_posts AS fp 
WHERE NOT EXISTS
  ( SELECT * 
    FROM banned_users AS bu
    WHERE bu.user_id = fp.user_id
  ) 
GROUP BY fp.user_id 
HAVING COUNT(*) >= 100   

3つの方法のどちらが速いかは、テーブルサイズや他の多くの要因によって異なるため、データを使用してテストすることをお勧めします。

于 2011-06-23T18:05:16.993 に答える
0

私にとって、2番目のクエリは、GROUP BYとHAVINGのレコード数を減らすため、より効率的です。

または、次のクエリを試して、INの使用を回避することもできます。

SELECT `fp`.`user_id`
FROM `forum_posts` `fp`
LEFT JOIN `banned_users` `bu` ON `fp`.`user_id` = `bu`.`user_id`
WHERE `bu`.`user_id` IS NULL
GROUP BY `fp`.`user_id`
HAVING COUNT(`fp`.`id`) >= 100

お役に立てれば。

于 2011-06-23T17:29:09.180 に答える
0

HAVING条件は、grouped by resultsに適用されます。また、user_idでグループ化するため、グループ化された結果にはすべての可能な値が含まれるため、user_id条件の配置は重要ではありません。

于 2011-06-23T16:34:56.570 に答える
-1

いいえ、同じ結果にはなりません。

最初のクエリはcount(id)条件からレコードをフィルタリングするため

別のクエリフィルターが記録し、having句を適用します。

2番目のクエリは正しく記述されています

于 2011-06-23T16:45:51.870 に答える