-
Bug
-
Resolution: Done
-
Blocker
-
4.0.0.Beta2
-
None
When firing this query
SELECT A.* FROM [nt:someTypeWithMixReferencable] AS A WHERE A.[jcr:uuid] = $uuid
There thould be an implicit index being used but it is not:
Access [A] Project [A] <PROJECT_COLUMNS=[A.[jcr:primaryType], A.[jcr:mixinTypes], A.[jcr:score], A.[mode:depth], A.[jcr:path], A.[jcr:name], A.[mode:localName], A.[mode:id]], PROJECT_COLUMN_TYPES=[STRING, STRING, DOUBLE, LONG, STRING, STRING, STRING, STRING]> Select [A] <SELECT_CRITERIA=A.[jcr:uuid] = $uuid> Select [A] <SELECT_CRITERIA=A.[jcr:primaryType] = 'nt:someTypeWithMixReferencable'> Source [A] <SOURCE_NAME=__ALLNODES__, SOURCE_ALIAS=A, SOURCE_COLUMNS=[jcr:frozenUuid(STRING), mode:sharedUuid(STRING), mode:nodeTypeName(STRING), jcr:defaultValues(STRING), mode:projectedNodeKey(STRING), jcr:mixinTypes(STRING), jcr:frozenPrimaryType(STRING), jcr:defaultPrimaryType(STRING), jcr:statement(STRING), jcr:lastModifiedBy(STRING), jcr:mimeType(STRING), jcr:hasOrderableChildNodes(BOOLEAN), jcr:etag(STRING), jcr:encoding(STRING), jcr:root(STRING), mode:kind(STRING), jcr:supertypes(STRING), jcr:successors(STRING), jcr:primaryItemName(STRING), jcr:hold(STRING), jcr:workspace(STRING), jcr:isDeep(BOOLEAN), jcr:primaryType(STRING), mode:externalNodeKey(STRING), mode:derivedFrom(STRING), mode:isHeldBySession(BOOLEAN), jcr:baseVersion(STRING), jcr:lastModified(DATE), jcr:mergeFailed(STRING), mode:derivedAt(DATE), jcr:requiredPrimaryTypes(STRING), jcr:multiple(BOOLEAN), mode:generated(BOOLEAN), jcr:activityTitle(STRING), jcr:lifecyclePolicy(STRING), jcr:isMixin(BOOLEAN), jcr:availableQueryOperators(STRING), jcr:childVersionHistory(STRING), jcr:content(STRING), jcr:autoCreated(BOOLEAN), mode:synchronous(BOOLEAN), name(STRING), mode:alias(STRING), jcr:createdBy(STRING), jcr:isFullTextSearchable(BOOLEAN), jcr:uuid(STRING), jcr:onParentVersion(STRING), mode:expirationDate(DATE), jcr:copiedFrom(STRING), mode:lockToken(STRING), jcr:title(STRING), jcr:isAbstract(BOOLEAN), jcr:versionableUuid(STRING), jcr:versionHistory(STRING), jcr:predecessors(STRING), jcr:lockIsDeep(BOOLEAN), jcr:lockOwner(STRING), mode:sha1(STRING), jcr:repository(STRING), mode:columnTypeName(STRING), jcr:created(DATE), jcr:frozenMixinTypes(STRING), jcr:description(STRING), jcr:text(STRING), jcr:host(STRING), jcr:configuration(STRING), jcr:port(STRING), mode:workspace(STRING), jcr:nodeTypeName(STRING), jcr:isQueryable(BOOLEAN), jcr:data(BINARY), jcr:language(STRING), jcr:isQueryOrderable(BOOLEAN), jcr:isCheckedOut(BOOLEAN), jcr:mandatory(BOOLEAN), jcr:protected(BOOLEAN), jcr:protocol(STRING), jcr:sameNameSiblings(BOOLEAN), jcr:requiredType(STRING), mode:lockingSession(STRING), jcr:messageId(STRING), jcr:id(STRING), mode:uri(STRING), mode:propertyName(STRING), mode:workspaces(STRING), privileges(STRING), mode:isSessionScoped(BOOLEAN), jcr:valueConstraints(STRING), jcr:retentionPolicy(STRING), jcr:activity(STRING), jcr:currentLifecycleState(STRING), jcr:score(DOUBLE), mode:depth(LONG), jcr:path(STRING), jcr:name(STRING), mode:localName(STRING), mode:id(STRING)]>
The query takes about 200 ms on a relatively empty repository. If I define an index on [jcr:uuid] myself, it takes under 20ms and I get this plan as a result:
Access [A] Project [A] <PROJECT_COLUMNS=[A.[jcr:primaryType], A.[jcr:mixinTypes], A.[jcr:score], A.[mode:depth], A.[jcr:path], A.[jcr:name], A.[mode:localName], A.[mode:id]], PROJECT_COLUMN_TYPES=[STRING, STRING, DOUBLE, LONG, STRING, STRING, STRING, STRING]> Select [A] <SELECT_CRITERIA=A.[jcr:uuid] = $uuid> Select [A] <SELECT_CRITERIA=A.[jcr:primaryType] = 'nt:someTypeWithMixReferencable'> Source [A] <SOURCE_NAME=__ALLNODES__, SOURCE_ALIAS=A, SOURCE_COLUMNS=[jcr:frozenUuid(STRING), mode:sharedUuid(STRING), mode:nodeTypeName(STRING), jcr:defaultValues(STRING), mode:projectedNodeKey(STRING), jcr:mixinTypes(STRING), jcr:frozenPrimaryType(STRING), jcr:defaultPrimaryType(STRING), jcr:statement(STRING), jcr:lastModifiedBy(STRING), jcr:mimeType(STRING), jcr:hasOrderableChildNodes(BOOLEAN), jcr:etag(STRING), jcr:encoding(STRING), jcr:root(STRING), mode:kind(STRING), jcr:supertypes(STRING), jcr:successors(STRING), jcr:primaryItemName(STRING), jcr:hold(STRING), jcr:workspace(STRING), jcr:isDeep(BOOLEAN), jcr:primaryType(STRING), mode:externalNodeKey(STRING), mode:derivedFrom(STRING), mode:isHeldBySession(BOOLEAN), jcr:baseVersion(STRING), jcr:lastModified(DATE), jcr:mergeFailed(STRING), mode:derivedAt(DATE), jcr:requiredPrimaryTypes(STRING), jcr:multiple(BOOLEAN), mode:generated(BOOLEAN), jcr:activityTitle(STRING), jcr:lifecyclePolicy(STRING), jcr:isMixin(BOOLEAN), jcr:availableQueryOperators(STRING), jcr:childVersionHistory(STRING), jcr:content(STRING), jcr:autoCreated(BOOLEAN), mode:synchronous(BOOLEAN), name(STRING), mode:alias(STRING), jcr:createdBy(STRING), jcr:isFullTextSearchable(BOOLEAN), jcr:uuid(STRING), jcr:onParentVersion(STRING), mode:expirationDate(DATE), jcr:copiedFrom(STRING), mode:lockToken(STRING), jcr:title(STRING), jcr:isAbstract(BOOLEAN), jcr:versionableUuid(STRING), jcr:versionHistory(STRING), jcr:predecessors(STRING), jcr:lockIsDeep(BOOLEAN), jcr:lockOwner(STRING), mode:sha1(STRING), jcr:repository(STRING), mode:columnTypeName(STRING), jcr:created(DATE), jcr:frozenMixinTypes(STRING), jcr:description(STRING), jcr:text(STRING), jcr:host(STRING), jcr:configuration(STRING), jcr:port(STRING), mode:workspace(STRING), jcr:nodeTypeName(STRING), jcr:isQueryable(BOOLEAN), jcr:data(BINARY), jcr:language(STRING), jcr:isQueryOrderable(BOOLEAN), jcr:isCheckedOut(BOOLEAN), jcr:mandatory(BOOLEAN), jcr:protected(BOOLEAN), jcr:protocol(STRING), jcr:sameNameSiblings(BOOLEAN), jcr:requiredType(STRING), mode:lockingSession(STRING), jcr:messageId(STRING), jcr:id(STRING), mode:uri(STRING), mode:propertyName(STRING), mode:workspaces(STRING), privileges(STRING), mode:isSessionScoped(BOOLEAN), jcr:valueConstraints(STRING), jcr:retentionPolicy(STRING), jcr:activity(STRING), jcr:currentLifecycleState(STRING), jcr:score(DOUBLE), mode:depth(LONG), jcr:path(STRING), jcr:name(STRING), mode:localName(STRING), mode:id(STRING)]> Index [A] <INDEX_SPECIFICATION=uuid, provider=local, cost~=100, cardinality~=0, selectivity~=0.0, constraints=[A.[jcr:uuid] = $uuid], INDEX_USED=true>
Testcase follows, it assumes there is one index being used without defining anything. Although I have never seen such in implicit index popping up in the plan.
@RunWith(CdiTestRunner.class) @TestControl(startScopes = RequestScoped.class, projectStage = UnitTest.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) //@Ignore public class WmModeshapeIndexWhenSearchingForUuidTest { @Inject private Session session; @Inject protected transient LogHelper logger; @Test public void test001CheckSomethingWithIndexes() throws RepositoryException, InterruptedException { regNodeType(session,"nt:someTypeWithMixReferencable"); //ensureIndex(indexManager(), "uuid", IndexDefinition.IndexKind.VALUE, "local", "nt:someTypeWithMixReferencable", "", null, "jcr:uuid", PropertyType.NAME); Node newNode1 = session.getRootNode().addNode("nodeWithSysName","nt:someTypeWithMixReferencable"); newNode1.addMixin("mix:referenceable"); session.save(); Thread.sleep(500); Query q = session.getWorkspace().getQueryManager().createQuery( "SELECT A.* FROM [nt:someTypeWithMixReferencable] AS A\n" + "WHERE A.[jcr:uuid] = $uuid",Query.JCR_SQL2); q.bindValue("uuid", session.getValueFactory().createValue(UUID.randomUUID().toString())); logger.info(q.getStatement()); QueryResult result = q.execute(); String plan = ((org.modeshape.jcr.api.query.QueryResult)result).getPlan(); logger.info(plan); Assert.assertEquals(1,countIndexes(plan)); } private int countIndexes(String plan){ Pattern p = Pattern.compile("INDEX_USED=true"); Matcher m = p.matcher(plan); int count = 0; while (m.find()){ count +=1; } return count; } protected IndexManager indexManager(){ if (!(session instanceof org.modeshape.jcr.api.Session)){ return null; } try { return ((org.modeshape.jcr.api.Session) session).getWorkspace().getIndexManager(); } catch (RepositoryException ex) { logger.error(ex.toString(), ex); } return null; } protected void ensureIndex(IndexManager manager, String indexName, IndexDefinition.IndexKind kind, String providerName, String indexedNodeType, String desc, String workspaceNamePattern, String propertyName, int propertyType) throws RepositoryException { if (manager.getIndexDefinitions().containsKey(indexName)){ return; } logger.info("registering index on property "+propertyName+", type "+indexedNodeType); // Create the index template ... IndexDefinitionTemplate template = manager.createIndexDefinitionTemplate(); template.setName(indexName); template.setKind(kind); template.setNodeTypeName(indexedNodeType); template.setProviderName(providerName); if (workspaceNamePattern != null) { template.setWorkspaceNamePattern(workspaceNamePattern); } else { template.setAllWorkspaces(); } if (desc != null) { template.setDescription(desc); } // Set up the columns ... IndexColumnDefinition colDefn = manager.createIndexColumnDefinitionTemplate().setPropertyName(propertyName).setColumnType(propertyType); template.setColumnDefinitions(colDefn); // Register the index ... manager.registerIndex(template, true); } private void regNodeType(Session repoSession, String typeName) throws RepositoryException{ NodeTypeManager mgr = repoSession.getWorkspace().getNodeTypeManager(); // Create a template for the node type ... NodeTypeTemplate type = mgr.createNodeTypeTemplate(); type.setName(typeName); type.setDeclaredSuperTypeNames(new String[]{CrConstants.JCR_NT_UNSTRUCTURED}); type.setAbstract(false); type.setOrderableChildNodes(true); type.setMixin(false); type.setQueryable(true); mgr.registerNodeType(type, true); } }