Summary
Add a cachepath attribute to <cfquery> and queryExecute() that prepends a custom prefix to auto-generated cache IDs, enabling efficient key-based cache management operations.
Problem Statement
Current Performance Issue
The existing tags attribute for query cache management stores tags in cache values, not keys. This means operations like cacheClear(["tagname"], "query") must:
- Retrieve all cache keys from the store (e.g., Redis)
- Read the complete value of every cached object
- Deserialize each object to check for matching tags
- Delete matching entries
Impact: In a Redis cache with 10,000+ cached queries, clearing by tag requires reading and deserializing all 10,000 objects, taking several seconds and blocking the application during the scan.
Auto-Generated Cache IDs
Additionally, Lucee auto-generates cache IDs as hashes based on SQL/datasource/credentials. This makes it impossible to:
- Selectively clear specific cached queries
- Check if a query is cached without executing it
- Debug cache contents effectively
Proposed Solution
Add a cachepath attribute that prepends a custom string to the auto-generated cache ID:
<cfquery name="users" datasource="myDB"
cachepath="users:active:"
cachedwithin="#createTimeSpan(0,1,0,0)#">
SELECT * FROM users WHERE active = 1
</cfquery>
Result: Cache ID becomes "users:active:A7F2E1C9D..." instead of just "A7F2E1C9D..."
Key Benefits
- Performance: Key-based cache clearing is O(k) where k = matching keys, vs O(n) where n = ALL cached objects
- Constant-time operations: Performance independent of total cache size—only matching keys are read
- Preserves uniqueness: Prepending maintains SQL/datasource hash, preventing conflicts
- Known key prefixes: Developers can use predictable prefixes for cache management
- Backward compatible: Zero impact on existing code
Use Case
1. Clear All User Queries
<cfquery cachepath="users:" cachedwithin="...">SELECT...</cfquery>
<!--- Clear only user queries, skip others --->
<cfset cacheRemove("users:*")> <!--- Fast: no deserialization --->
Compatibility
-
Fully backward compatible—existing queries work unchanged
-
Works with all cache handlers (RAM, Redis, EHCache, Memcached)
-
No breaking changes to cache ID generation for queries without
cachepath