baomidou/mybatis-plus · error · MybatisPlusException
非法SQL,SQL未使用到索引, table:{}, columnName:{}
Error message
非法SQL,SQL未使用到索引, table:{}, columnName:{} What it means
Thrown by IllegalSQLInnerInterceptor (jsqlparser 5.0 variant) during index validation: after collecting IndexInfo metadata from the JDBC connection, if the first WHERE column of the table does not match any indexed column name, the interceptor rejects the SQL as '未使用到索引' (no index used), naming the table and column. It enforces the rule that the leading WHERE predicate must hit an index.
Source
Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser-5.0/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/IllegalSQLInnerInterceptor.java:248
private void validUseIndex(Table table, String columnName, Connection connection) {
//是否使用索引
boolean useIndexFlag = false;
if (StringUtils.isNotBlank(columnName)) {
//表存在的索引
String dbName = table.getSchemaName();
String tableName = table.getName();
String catalogName = table.getCatalogName();
columnName = SqlParserUtils.removeWrapperSymbol(columnName);
List<IndexInfo> indexInfos = getIndexInfos(catalogName, dbName, tableName, connection);
for (IndexInfo indexInfo : indexInfos) {
if (indexInfo.getColumnName().equalsIgnoreCase(columnName)) {
useIndexFlag = true;
break;
}
}
}
if (!useIndexFlag) {
throw new MybatisPlusException("非法SQL,SQL未使用到索引, table:" + table.getName() + ", columnName:" + columnName);
}
}
/**
* 验证where条件的字段,是否有not、or等等,并且where的第一个字段,必须使用索引
*
* @param expression ignore
* @param table ignore
* @param connection ignore
*/
private void validWhere(Expression expression, Table table, Connection connection) {
validWhere(expression, table, null, connection);
}
/**
* 验证where条件的字段,是否有not、or等等,并且where的第一个字段,必须使用索引
*
* @param expression ignoreView on GitHub (pinned to bf67d90747)
Solutions
- Add an index on the leading WHERE column: CREATE INDEX idx_order_status ON t_order(status)
- Reorder the WHERE clause so an indexed column comes first in the parsed expression
- Verify the connected database/catalog actually contains the index (check SHOW INDEX / user_indexes) — wrong dbName or catalog in getIndexInfos makes every lookup fail
- If full-table scans are intentional (small tables, reports), disable the index-check portion or the whole IllegalSQLInnerInterceptor for that statement/environment
Example fix
-- before: SELECT * FROM t_order WHERE status = ?; -- status not indexed CREATE INDEX idx_t_order_status ON t_order(status); -- after: SELECT * FROM t_order WHERE status = ?; -- interceptor passes
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the leading WHERE column is indexed before running intercepted SQL
try (Connection c = dataSource.getConnection()) {
DatabaseMetaData md = c.getMetaData();
boolean indexed;
try (ResultSet rs = md.getIndexInfo(null, null, "t_order", false, false)) {
indexed = false;
while (rs.next()) {
if ("status".equalsIgnoreCase(rs.getString("COLUMN_NAME"))) { indexed = true; break; }
}
}
if (!indexed) throw new IllegalStateException("t_order.status has no index; interceptor will reject");
} Try / catch
try {
return orderMapper.selectByStatus(status);
} catch (MybatisPlusException e) {
if (e.getMessage() != null && e.getMessage().contains("未使用到索引")) {
// route to a statement whose leading column is indexed, or surface an ops error
throw new IllegalStateException("Leading WHERE column lacks index — create one or reorder predicates", e);
}
throw e;
} Prevention
- Add indexes for columns used as leading WHERE predicates before enabling the interceptor
- Keep schema migrations and interceptor rollout in the same release train
- Ensure the JDBC URL's schema/catalog matches where indexes were created
When it happens
Trigger: Registering IllegalSQLInnerInterceptor (optionally with index check enabled) and executing a query whose first WHERE column has no matching index in DatabaseMetaData — e.g. WHERE status = ? where status is a non-indexed column, or where the column is wrapped/aliased so its name doesn't string-match an IndexInfo column.
Common situations: Enabling the interceptor on a schema where leading filter columns lack indexes; case/schema mismatch between the mapper column name and JDBC metadata; developers testing against H2 where production MySQL indexes don't exist; hitting the check on large full-table-scan reports.
Related errors
- 非法SQL,where条件中不能使用数据库函数,错误函数信息:{}
- 非法SQL,where条件中不能使用【or】关键字,错误or信息:
- 非法SQL,SQL未使用到索引, table:
- 非法SQL,where条件中不能使用数据库函数,错误函数信息:{}
- 非法SQL,SQL未使用到索引, table:{}, columnName:{}
AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14).
Data as JSON: /api/errors/2c1dbb85f4fa355f.
Report an issue: GitHub.