簡體   English   中英

在第二個表 MySQL 上左加入 2 個表時的索引

[英]Indexes when left joining 2 tables with order by on second table MySQL

對於有經驗的用戶來說,這可能很容易,但我無法完全理解這個簡單案例需要哪些索引。

除了一些可用於搜索目的的過濾器之外,我有一個可以按任何列排序的前端表:

id | username | email | name | phone | email_verified_at

顯示的行是連接 2 個表的結果(具有一對一關系):

TABLE USERS

id | autoincrement
name | string
username | string | unique
email | string | unique
email_verified_at | timestamp | nullable

INDEXES
primary(id)
unique(name,id)
unique(username)
unique(email)
unique(email_verified_at,email)
TABLE PROFILES

id | autoincrement
user_id | FK(users)
phone | string

INDEXES
primary(id)
index(user_id)
unique(phone,user_id)

最基本的查詢,按用戶 ID 排序,看起來像

select
  `users`.`id` as `id`,
  `users`.`name` as `name`,
  `users`.`username` as `username`,
  `users`.`email` as `email`,
  `users`.`email_verified_at` as `email_verified_at`,
  `profiles`.`phone` as `phone`
from
  `users`
  left join `profiles` on `users`.`id` = `profiles`.`user_id`
order by
  `id` asc
limit
  11

按 id、名稱、用戶名、email 或 email_verified_at 排序在用戶表中執行全索引掃描,我認為這是正確的。

在此處輸入圖像描述

但是當我嘗試通過電話訂購時,麻煩(或沒有)來了:

select
  `users`.`id` as `id`,
  `users`.`name` as `name`,
  `users`.`username` as `username`,
  `users`.`email` as `email`,
  `users`.`email_verified_at` as `email_verified_at`,
  `profiles`.`phone` as `phone`
from
  `users`
  left join `profiles` on `users`.`id` = `profiles`.`user_id`
order by
  `phone` asc
limit
  11

我看到的第一件事是它正在用戶表中進行全表掃描。 為了避免這種情況,我需要為 users 表創建一個 UNIQUE 索引,其中包含:

id, username, email, name

因此,查詢對 users 表執行 FULL INDEX SCAN。 盡管如此,我發現與按用戶表字段排序相比,查詢成本太高了。

在此處輸入圖像描述

那樣行嗎? 我在這里錯過了什么嗎? 我不確定這是預期結果還是可以改進。

提前致謝

profiles需要一個以user_id開頭的索引。 索引中列的順序很重要。

如需進一步討論,請提供SHOW CREATE TABLEEXPLAIN FORMAT=JSON SELECT...

暫無
暫無

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

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