1. ホーム
  2. mysql

[解決済み] MySQLの "IN "演算子による(大量の)値に対するパフォーマンス

2022-11-19 05:46:05

質問

最近RedisとMongoDBを試しているのですが、RedisとMongoDBに格納された配列に idの を保存する場合が多いようです。この質問では、MySQLの IN 演算子について質問しているからです。

を大量(300~3000)にリストアップするのは、どの程度のパフォーマンスなのか気になりました。 idの を IN 演算子の内部でリストアップする場合、以下のようになります。

SELECT id, name, price
FROM products
WHERE id IN (1, 2, 3, 4, ...... 3000)

のような単純なものを想像してください。 製品 カテゴリ というテーブルがあり、通常はこれをJOINして 製品 を取得するために カテゴリ . 上の例では、Redis のあるカテゴリの下 ( category:4:product_ids ) で、ID 4 のカテゴリからすべての商品 ID を返し、それらを上記の SELECT クエリの中の IN 演算子で囲みます。

これはどの程度のパフォーマンスなのでしょうか?

これは、quot;it depends"という状況なのでしょうか?それとも、具体的な "this is (un)acceptable" や "fast" や "slow" があるのでしょうか? LIMIT 25 とか、それは役に立たないのでしょうか?

SELECT id, name, price
FROM products
WHERE id IN (1, 2, 3, 4, ...... 3000)
LIMIT 25

それとも、Redisが返す商品IDの配列を25に制限するためにトリミングして、3000ではなく25のIDだけをクエリに追加して LIMIT -を使用してクエリ内部から25個に制限する必要がありますか?

SELECT id, name, price
FROM products
WHERE id IN (1, 2, 3, 4, ...... 25)

何か提案やフィードバックがあれば、ぜひお願いします。

どのように解決するのですか?

一般的に言えば、もし IN リストが大きくなりすぎた場合(「大きくなりすぎた」の定義が不明確で、通常は100以下の領域です)、結合を使用する方が効率的になり、数字を保持するために必要であれば一時テーブルを作成します。

数値が密なセット(ギャップがない - サンプルデータが示唆しています)である場合、以下の方法でさらにうまくいくでしょう。 WHERE id BETWEEN 300 AND 3000 .

しかし、おそらくセットにはギャップがあり、その場合は結局のところ有効な値のリストで行く方がよいかもしれません(ギャップが比較的少ない場合を除き、その場合は

WHERE id BETWEEN 300 AND 3000 AND id NOT BETWEEN 742 AND 836

とか、隙間は何でもいい。