diff --git a/planner/core/cacheable_checker.go b/planner/core/cacheable_checker.go
index <HASH>..<HASH> 100644
--- a/planner/core/cacheable_checker.go
+++ b/planner/core/cacheable_checker.go
@@ -82,6 +82,11 @@ func (checker *cacheableChecker) Enter(in ast.Node) (out ast.Node, skipChildren 
 				return in, true
 			}
 		}
+	case *ast.FrameBound:
+		if _, ok := node.Expr.(*driver.ParamMarkerExpr); ok {
+			checker.cacheable = false
+			return in, true
+		}
 	}
 	return in, false
 }
diff --git a/planner/core/cacheable_checker_test.go b/planner/core/cacheable_checker_test.go
index <HASH>..<HASH> 100644
--- a/planner/core/cacheable_checker_test.go
+++ b/planner/core/cacheable_checker_test.go
@@ -191,4 +191,7 @@ func (s *testCacheableSuite) TestCacheable(c *C) {
 		OrderBy: orderByClause,
 	}
 	c.Assert(Cacheable(stmt), IsTrue)
+
+	boundExpr := &ast.FrameBound{Expr: &driver.ParamMarkerExpr{}}
+	c.Assert(Cacheable(boundExpr), IsFalse)
 }
planner: make WindowFunction uncacheable in prepare (#<I>)