























这是一个创建于 586 天前的主题,其中的信息可能已经有所发展或是发生改变。
假设有一张 software 表,表结构如下
| software_id (int) | author_id (int) | create_time | update_time |
|---|---|---|---|
| 1 | 1 | 2024-11-05 11:00:00 | 2024-11-05 11:00:00 |
| 2 | 2 | 2024-11-05 11:00:00 | 2024-11-05 11:00:00 |
其中 software_id 是主键,author_id 是普通索引
还有一张 company_software 表,表结构如下
| company_software_id (int) | author_id (int) | country(varchar) | software_id (varchar) |
|---|---|---|---|
| 1 | 1 | china | 1 |
| 2 | 1 | china | kkk |
其中 company_software_id 是主键,author_id 、country 、software_id 是一个复合索引。
以上表数据量只有 1~5w 。
1 、SQL1
SELECT 1
FROM company_software AS company_software
WHERE company_software.author_id = 1
and company_software.country in ('china', 'korea', 'england')
and company_software.software_id = '1'
并不会导致慢查询
2 、SQL2
SELECT software_id
FROM sortware
WHERE author_id = 1
and NOT EXISTS (SELECT 1
FROM company_software AS company_software
WHERE company_software.author_id = 1
and company_software.country in ('china', 'korea', 'england')
and CONVERT(sortware.software_id , char) = company_software.software_id)
LIMIT 0, 100
为什么会导致慢查询,懂的大佬帮忙分析下
第 1 条附言 · 2024 年 11 月 5 日
SQL
explain SELECT software_id
FROM software
WHERE author_id = 1
and NOT EXISTS (SELECT 1
FROM company_software AS company_software
WHERE company_software.author_id = 1
and company_software.country in ('china', 'korea', 'england')
and CONVERT(software.software_id , char) = company_software.software_id)
LIMIT 0, 100;
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | PRIMARY | software | ref | idx_authorid | idx_authorid | 5 | const | 1 | 100 | Using where; Using index | |
| 2 | DEPENDENT SUBQUERY | company_software | ref | idx_authorid_country_softwareid | idx_authorid_country_softwareid | 5 | const | 8 | 50 | Using where; Using index |
software只有一条数据,company_software有八条数据,country都是china
1 admol 2024 年 11 月 5 日and sortware.software_id = CONVERT(company_software.software_id , char) 换一下顺序试试 |
3 wuych 2024 年 11 月 5 日 via iPhone子查询的 where 里用了函数之后你的整个子查询就不走索引了吧,你把那个 convert 放到外面呗。 |
7 newboy1 2024 年 11 月 5 日另外如果不使用 in 查询,直接使用等值查询,并不会出现慢查询 |
8 seedhk 2024 年 11 月 5 日贴一下执行计划 |
11 fengpan567 2024 年 11 月 5 日CONVERT(sortware.software_id , char) = company_software.software_id 导致的慢查询,分两步查吧 |
12 Chinsung 2024 年 11 月 6 日你贴个 explain 结果然后说你不理解我都可以理解 |
13 redog 2024 年 11 月 6 日如果我没有弄错的话 是因为 NOT EXISTS 的原因,这里会导致你最后一个 where CONVERT(sortware.software_id , char) = company_software.software_id 这个是无效的,因为在 mysql 看来,这里不用专门去匹配,直接按前面的条件取回 N 条记录,在这 N 条记录里去检查 software_id 就行了。 这样会导致外层查询时子查询里返回的不是一条记录,而是一堆记录,在这一堆记录里去判断 software_id 是否相等,应该试试用 not in 本质是 inner join 这样会先按索引来一次性筛选,而不是每一条都要去筛选。 |
14 coderzhangsan 2024 年 11 月 6 日有一点不明白,为什么 software_id 在一张表是主键 id(int 类型),另一张表则是 varchar 类型,难道不应该数据类型一致吗?开发中,如果不注意的化,查询会导致隐式转换,这就导致你的 SQL 必须用函数转换,因而 SQL 查询变得复杂。 |
15 isnullstring 2024 年 11 月 6 日where 语句里使用函数 都是导致索引失效喔 相同字段在不同表定不同类型,一开始写代码赶工期、马虎了事,跟我现在接手的系统一毛一样 |
16 redog 2024 年 11 月 7 日另外你的类型不一致,要进行一次手动转换,不然还是会回到 DEPENDENT SUBQUERY ,具体的话,你应该试试: |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。