简体   繁体   English

在第二个表 MySQL 上左加入 2 个表时的索引

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

This may be so easy for an experienced user, but I'm no able to fully understand what indexes are needed for this simple case.对于有经验的用户来说,这可能很容易,但我无法完全理解这个简单案例需要哪些索引。

I have a front-end table that can be sorted by any column besides some filters that can be applied for searching purposes:除了一些可用于搜索目的的过滤器之外,我有一个可以按任何列排序的前端表:

id | username | email | name | phone | email_verified_at

The rows shown is a result of joining 2 tables (with a one-to-one relationship):显示的行是连接 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)

The most basic query, ordered by user id looks like最基本的查询,按用户 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

Ordering by id, name, username, email, or email_verified_at performs a FULL INDEX SCAN in users table which I assume is correct.按 id、名称、用户名、email 或 email_verified_at 排序在用户表中执行全索引扫描,我认为这是正确的。

在此处输入图像描述

But the trouble (or not) comes when I try to order by phone:但是当我尝试通过电话订购时,麻烦(或没有)来了:

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

The first thing I see is that it's doing a FULL TABLE SCAN in users table.我看到的第一件事是它正在用户表中进行全表扫描。 In order to avoid that I need to create a UNIQUE index for users table containing:为了避免这种情况,我需要为 users 表创建一个 UNIQUE 索引,其中包含:

id, username, email, name

Therefore the query performs a FULL INDEX SCAN over users table.因此,查询对 users 表执行 FULL INDEX SCAN。 Despite that, I'm seeing that query cost is too high compared to sorting by users table fields.尽管如此,我发现与按用户表字段排序相比,查询成本太高了。

在此处输入图像描述

Is that OK?那样行吗? Am I missing something here?我在这里错过了什么吗? I'm not sure if this is an expected result or it can be improved.我不确定这是预期结果还是可以改进。

Thanks in advance提前致谢

profiles needs an index starting with user_id . profiles需要一个以user_id开头的索引。 The order of the columns in an index does matter.索引中列的顺序很重要。

For further discussion, please provide SHOW CREATE TABLE and EXPLAIN FORMAT=JSON SELECT...如需进一步讨论,请提供SHOW CREATE TABLEEXPLAIN FORMAT=JSON SELECT...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM