簡體   English   中英

我怎樣才能加快這個連接表本身的查詢?

[英]How can I speed up this query that joins a table on itself?

我們有一個“用戶”表,用於保存有關我們用戶的信息。 此表中的字段之一稱為“查詢”。 我正在嘗試選擇具有相同查詢的所有用戶的用戶 ID。 所以我的輸出應該是這樣的:

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

不幸的是,我無法在一小時內完成此查詢(用戶表非常大)。 這是我當前的查詢:

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' 列的值為 11,而不是 1。有什么我可以做的來加速這個查詢嗎? 我的“<>”比較是否在 join 不好的做法中? 此外,id 字段是主鍵

查詢的主要驅動因素是query字段的相等性——如果它被索引。 id的 <> 可能不是很具體,它通過用於它的選擇類型顯示為 'ref'

以下僅適用於“查詢”未編入索引的情況....

如果id是主鍵,你可以這樣做:

CREATE INDEX index_1  ON users (query);

添加此類索引的結果將是查詢的覆蓋索引,並將導致查詢的最快執行。

我最關心的是key_len ,它表明 MySQL 必須比較最多 768 個字節才能查找每個索引條目。

對於此查詢,對哈希索引query可能會更加高性能的(因為它會涉及短得多的比較,在計算哈希值,並使用該指數是無法排序記錄的費用):

ALTER TABLE users ADD INDEX (query) USING HASH

您還可以考慮將其作為(query, id)的組合(query, id)以便 MySQL 無需掃描到記錄本身來測試<>標准。

你有多少查詢? 您可以添加表 UsersInQueries:

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

然后從此表中選擇並按 queryId 分組

如果每個查詢最多只有兩個用戶,則可以改為執行以下操作:

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

如果你有兩個以上的用戶使用相同的查詢,你能解釋為什么你想要所有這樣的用戶對嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM