2

ユーザーに関する情報を保持する「users」テーブルがあります。このテーブル内のフィールドの 1 つは「クエリ」と呼ばれます。同じクエリを持つすべてのユーザーのユーザー ID を選択しようとしています。したがって、私の出力は次のようになります。

user1_id    user2_id    common_query
   43          2            "foo"
   117         433          "bar"
   1           119          "baz"
   1           52           "qux"

残念ながら、このクエリを 1 時間以内に完了することはできません (users テーブルがかなり大きいため)。これは私の現在のクエリです:

SELECT u1.id,
       u2.id,
       u1.query
FROM users u1
INNER JOIN users u2
        ON u1.query = u2.query
       AND u1.id <> u2.id

私の説明:

+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+
| id | select_type | table | type  | possible_keys        | key                  | key_len | ref                             | rows     | Extra                    |
+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+
|  1 | SIMPLE      | u1    | index | index_users_on_query | index_users_on_query | 768     | NULL                            | 10905267 | Using index              |
|  1 | SIMPLE      | u2    | ref   | index_users_on_query | index_users_on_query | 768     | u1.query                        |       11 | Using where; Using index |
+----+-------------+-------+-------+----------------------+----------------------+---------+---------------------------------+----------+--------------------------+

説明からわかるように、users テーブルはクエリでインデックスが作成され、そのインデックスは私の SELECT で使用されているようです。テーブル u2 の「rows」列の値が 1 ではなく 11 である理由が気になります。このクエリを高速化するためにできることはありますか? 私の '<>' 比較は結合の悪い習慣ですか? また、id フィールドは主キーです

4

4 に答える 4

1

クエリの主な推進要因は、queryフィールドの同等性です(インデックスが作成されている場合)。への<>idはおそらくあまり具体的ではなく、使用されているselectのタイプによって示されます'ref'

以下は、「query」がインデックス付けされていない場合にのみ適用されます。

が主キーの場合id、これを行うことができます。

CREATE INDEX index_1  ON users (query);

このようなインデックスを追加した結果、クエリのカバーインデックスになり、クエリの実行が最速になります。

于 2012-11-19T19:10:50.840 に答える
1

私の最大の関心事は、key_lenMySQL が各インデックス エントリを検索するために最大 768 バイトを比較する必要があることを示しています。

このクエリでは、上のハッシュ インデックスを使用queryすると、はるかにパフォーマンスが向上する可能性があります (ハッシュを計算し、そのインデックスを使用してレコードを並べ替えることができないという犠牲を払って、大幅に短い比較が必要になるため)。

ALTER TABLE users ADD INDEX (query) USING HASH

MySQL が基準(query, id)をテストするためにレコード自体をスキャンする必要がないように、これをコンポジットにすることも検討してください。<>

于 2012-11-19T19:22:05.333 に答える
0

クエリごとに最大2人のユーザーしかない場合は、代わりに次のようにすることができます。

select query, min(id) as FirstID, max(id) as SecondId
from users
group by query
having count(*) > 1

同じクエリで3人以上のユーザーがいる場合、そのようなユーザーのすべてのペアが必要な理由を説明できますか?

于 2012-11-19T19:21:20.660 に答える
0

クエリはいくつありますか?テーブルUsersInQueriesを追加できます。

id   queryId   userId
0      5         453   
1      23        732 
2      15        761

次に、このテーブルから選択し、queryIdでグループ化します

于 2012-11-19T19:10:50.583 に答える