# [FAQ] 使用 Prepared statement 与否导致执行计划不同

## Key Words

prepared statement, prepared plan cache, 执行计划, 程序, 客户端

## Description

程序里执行 SQL 是通过 prepared statement 执行的，执行计划是 TableFullScan；  
客户端是直接执行，没有通过 prepared statement，执行计划是较高效率的 IndexRangeScan。

## Content

主要原因可以概况为 Prepared plan cache 会禁止一些和具体参数值密切相关的激进查询优化手段导致对特定的一些参数值，查询计划可能不是最优。  
Issue [tidb#40093](https://github.com/pingcap/tidb/issues/40093) 描述了更为详细的现象：

1. `select * from t1 where a > ? and a < ?`，由于 a 参数可能出现 table dual，所以会选更差的 plan
2. `select * from t where a in (?, ?)`，列是 int，参数传的是 decimal，即参数类型不匹配导致不能选择索引
3. 在 outer join 的情况下，使用了 in，in 里面有参数，planner 会检查这些条件是否为 NULL，但参数会影响此项检查，导致 in 无法下推到 outer join，也会选错执行计划

解决方法：关闭 Prepared plan cache，或者通过 hint [IGNORE_PLAN_CACHE()](https://docs.pingcap.com/zh/tidb/stable/optimizer-hints#ignore_plan_cache) 跳过。

## Affected Versions

All
