baomidou/mybatis-plus · error · MybatisPlusException

非法SQL,SQL未使用到索引, table:

Error message

非法SQL,SQL未使用到索引, table:

What it means

Non-5.0 variant of the index check: IllegalSQLInnerInterceptor collects IndexInfo via getIndexInfos(null, catalogName, dbName, tableName, connection) and, when the leading WHERE column matches no indexed column name, throws 'SQL未使用到索引' naming table and column. The leading predicate must be covered by an index visible through JDBC DatabaseMetaData.

Source

Thrown at mybatis-plus-jsqlparser-support/mybatis-plus-jsqlparser/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(null, 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 ignore

View on GitHub (pinned to bf67d90747)

Solutions

  1. Create the missing index on the leading WHERE column
  2. Reorder predicates so an indexed column leads the WHERE expression
  3. Confirm dbName/catalog in the JDBC URL and table reference match where the index lives (SHOW INDEX FROM t)
  4. Temporarily disable the index check or interceptor for statements where a scan is intentional

Example fix

-- before: interceptor rejects WHERE tenant_id = ? on t_order
classpath: schema.sql
CREATE INDEX idx_t_order_tenant_id ON t_order(tenant_id);
-- after: same query passes validation
Defensive patterns

Strategy: try-catch

Validate before calling

// Assert the leading WHERE column is indexed before enabling/executing
try (Connection c = dataSource.getConnection();
     ResultSet rs = c.getMetaData().getIndexInfo(null, c.getCatalog(), "t_order", false, false)) {
    boolean found = false;
    while (rs.next()) {
        if ("tenant_id".equalsIgnoreCase(rs.getString("COLUMN_NAME"))) { found = true; break; }
    }
    if (!found) throw new IllegalStateException("Missing index on t_order.tenant_id");
}

Try / catch

try {
    return orderMapper.byTenant(tenantId);
} catch (MybatisPlusException e) {
    if (e.getMessage() != null && e.getMessage().contains("未使用到索引")) {
        throw new IllegalStateException("Leading WHERE column unindexed — fix schema or reorder predicate", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Registering the interceptor with index validation enabled and running a query whose first WHERE column is unindexed; also when dbName/catalog passed to metadata lookup is wrong so index lookup returns an empty list and every column 'fails'.

Common situations: Schema drift between environments (index exists in prod, not in the dev DB the app connects to); column name case mismatch with JDBC metadata; table referenced via alias or schema prefix confusing the lookup; teams enabling the check before back-filling indexes.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/be95389abd2d8a51. Report an issue: GitHub.