Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.Original topic: 奇怪的慢查全表扫描

[TiDB Usage Environment] Production Environment / Testing / Poc
[TiDB Version]
[Reproduction Path] What operations were performed to encounter the issue
[Encountered Issue: Problem Phenomenon and Impact]
[Resource Configuration]
select * from db1.account where id in (select
case when JSON_EXTRACT(response,'$.status') = 'OK' then JSON_EXTRACT(response,'$.result.one_face_with_multi_cards[0].user_id')
else ' ' end as concat_top_max_user_id
from db1.face where account_id = 1000000
and option_type = 2
order by id desc limit 1)
The execution plan causes a full table scan on db1.account.
db1.account.id, decimal(20,0) BINARY) → Column#65, a forced conversion is clearly happening.
If you first retrieve the result and then execute select * from db1.account where id (xxxx), it uses Batch_Point_Get_1.
Then, modify the subquery to cast(case …when… end as unsigned).
Using convert yields the same result.
Finally, perform the cast conversion in the case branch, resulting in:
cast(case when JSON_EXTRACT(response,'$.status') = 'OK' then cast(JSON_EXTRACT(response,'$.result.one_face_with_multi_cards[0].user_id') as unsigned)
else '' end as unsigned)
The final statement is:
select * from db1.account where id in (select
cast(case when JSON_EXTRACT(response,'$.status') = 'OK' then cast(JSON_EXTRACT(response,'$.result.one_face_with_multi_cards[0].user_id') as unsigned)
else '' end as unsigned) as concat_top_max_user_id
from db1.face where account_id = 1000000
and option_type = 2
order by id desc limit 1)
Finally solved it. Why are two cast conversions needed?