【发布时间】:2023-02-14 09:59:20
【问题描述】:
这是我的 MySQL 查询,我使用了 LEFT JOIN:
SELECT ph.id, ph.number
FROM phone ph
LEFT JOIN linked_phones lp ON ph.number = lp.number
WHERE ph.userid = 10 and ph.active = 1 AND ph.linkid = 50 AND lp.number IS null
我想把所有没有关联的号码都选出来,但是执行时间太长了(500多秒)。 我在两个表上添加了索引:
- 桌面电话的第一个索引:links idx(user id, active, linkedin )
- 表 linked_phones 的第二个索引:number_idx(number)
这里有 EXPLAIN 查询的结果:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | ph | ref | links_idx | links_idx | 12 | const,const,const | 127935 | |
| 1 | SIMPLE | al | ALL | name_idx,number_idx | 84355 | Range checked for each record (index map: 0xA); Not exists |
当我仅从电话表执行第一部分时:
select count(1)
from phone
where userid = 10 and active=1 AND linkid =50
它很快给出了结果:超过 84506 行
当我从另一个表执行第二部分时:
select count(1) from linked_phones where userid = 10
它也很快给了我结果:85149 行
我也尝试过使用子查询但同样的问题:
select id, number
from phone
where userid = 10 and active =1 AND linkid = 50
and number not in (select number from linked_phones where);
对于优化此查询的任何建议,我将不胜感激。
【问题讨论】:
-
您能检查您的 2 个“数字”列的数据类型是否匹配吗?
-
您的索引实际上看起来不错但你为什么使用
LIMIT而不使用ORDER BY? -
@Solarflare 是的,我检查发现电话表中的号码是
bigint(25),但另一个表中的号码是char(64),问题是我无权更改这些列 -
@TimBiegeleisen 我刚刚添加了它来检查它是否有帮助并忘记删除它抱歉我更新了查询
-
哦,我的我的。存储为数字数据类型的电话号码。那是残酷的数据设计。