在第二个表 MySQL 上按顺序加入 2 个表时的索引
Posted
技术标签:
【中文标题】在第二个表 MySQL 上按顺序加入 2 个表时的索引【英文标题】:Indexes when left joining 2 tables with order by on second table MySQL 【发布时间】:2021-07-22 10:51:19 【问题描述】:对于有经验的用户来说这可能很容易,但我无法完全理解这个简单案例需要哪些索引。
除了一些可用于搜索目的的过滤器之外,我有一个可以按任何列排序的前端表:
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_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
我看到的第一件事是它正在用户表中进行全表扫描。 为了避免我需要为包含以下内容的用户表创建一个唯一索引:
id, username, email, name
因此,查询对用户表执行全索引扫描。 尽管如此,与按用户表字段排序相比,我发现查询成本太高了。
这样好吗?我在这里错过了什么吗?我不确定这是预期结果还是可以改进。
提前致谢
【问题讨论】:
【参考方案1】:profiles
需要一个以user_id
开头的索引。索引中列的顺序很重要。
如需进一步讨论,请提供SHOW CREATE TABLE
和EXPLAIN FORMAT=JSON SELECT ...
【讨论】:
以上是关于在第二个表 MySQL 上按顺序加入 2 个表时的索引的主要内容,如果未能解决你的问题,请参考以下文章
如果一个表的列等于第二个表中的列,则在第三个表中插入值,python - mysql