Problemen met trage query's oplossen

Trage Query-classificaties

Er zijn drie belangrijke classificaties van langzame vragen in AEM, die door strengheid worden vermeld:

  1. Vragen zonder index

    • Vragen die not oplossen aan een index en de inhoud van JCR doorlopen om resultaten te verzamelen
  2. Slecht beperkte (of scoped) vragen

    • Vragen die tot een index worden opgelost, maar alle indexitems moeten doorlopen om resultaten te verzamelen
  3. Vraagstukken met een grote resultaatset

    • Zoekopdrachten die een zeer groot aantal resultaten opleveren

De eerste 2 classificaties van vragen (index-minder en slecht beperkt) zijn langzaam, omdat zij de de vraagmotor van het Eak dwingen om elk potentieel resultaat (inhoudknooppunt of indexingang) te inspecteren om te identificeren die in werkelijk resultaatreeks behoren.

Het inspecteren van elk mogelijk resultaat is de zogenaamde "Traversing".

Aangezien elk potentieel resultaat moet worden geïnspecteerd, stijgen de kosten om de feitelijke resultaatreeks te bepalen lineair met het aantal potentiële resultaten.

Door querybeperkingen en tuning-indexen toe te voegen, kunnen de indexgegevens worden opgeslagen in een geoptimaliseerde indeling die snelle resultaten ophaalt en, vermindert of verwijdert u de behoefte aan lineaire inspectie van potentiële resultaatsets.

In AEM 6.3, door gebrek, wanneer een traversal van 100.000 wordt bereikt, ontbreekt de vraag en werpt een uitzondering. Deze grens bestaat niet door gebrek in AEM versies voorafgaand aan AEM 6.3, maar kan via de Montages OSGi van de Motor van de Vraag van het Jasje van de Vraag van Apache worden geplaatst en Bon QueryEngineSettings JMX (bezit LimitReads).

Vragen zonder index detecteren

Tijdens ontwikkeling

Verklaar all vragen en zorg ervoor hun vraagplannen /&ast niet bevatten; doorlopen uitleg erin. Voorbeeld dat queryplan doorloopt:

  • PLAN: [nt:unstructured] as [a] /* traverse "/content//*" where ([a].[unindexedProperty] = 'some value') and (isdescendantnode([a], [/content])) */

na implementatie

  • Controleer error.log voor index-less traversal vragen:

    • *INFO* org.apache.jackrabbit.oak.query.QueryImpl Traversal query (query without index) ... ; consider creating and index
    • Dit bericht wordt slechts geregistreerd als geen index beschikbaar is, en als de vraag potentieel vele knopen oversteekt. De berichten worden niet geregistreerd als een index beschikbaar is, maar het bedrag aan het oversteken is klein, en zo snel.
  • Bezoek de AEM Query Performance bewerkingsconsole en Verklaar langzame query's die op doorlopende of geen uitleg voor indexquery zoeken.

Slecht beperkte query's detecteren

Tijdens ontwikkeling

Verklaar alle vragen en zorg ervoor zij aan een index oplossen die wordt afgestemd om de het bezitsbeperkingen van de vraag aan te passen.

  • De ideale dekking van het vraagplan heeft indexRules voor alle bezitsbeperkingen, en bij een minimum voor de strengste bezitsbeperkingen in de vraag.
  • Vragen die resultaten sorteren, zouden aan een Index van het Bezit van Lucene met indexregels voor de gesorteerde door eigenschappen moeten oplossen die orderable=true. plaatsen

De standaard cqPageLucene heeft bijvoorbeeld geen indexregel voor jcr:content/cq:tags

Voordat u de indexregel cq:tags toevoegt

  • cq:labels, indexregel

    • Bestaat niet buiten het vak
  • Query Builder-query

    type=cq:Page
     property=jcr:content/cq:tags
     property.value=my:tag
    
  • Zoekplan

    • [cq:Page] as [a] /* lucene:cqPageLucene(/oak:index/cqPageLucene) *:* where [a].[jcr:content/cq:tags] = 'my:tag' */

Deze query wordt omgezet in de cqPageLucene-index, maar omdat er geen eigenschapsindexregel bestaat voor jcr:content of cq:tags, wordt bij het evalueren van deze beperking elke record in de cqPageLucene-index gecontroleerd om een overeenkomst te bepalen. Dit betekent dat als de index 1 miljoen cq:Page knopen bevat, dan 1 miljoen verslagen worden gecontroleerd om de resultaatreeks te bepalen.

Na het toevoegen van de regel cq:tags index

  • cq:labels, indexregel

    /oak:index/cqPageLucene/indexRules/cq:Page/properties/cqTags
     @name=jcr:content/cq:tags
     @propertyIndex=true
    
  • Query Builder-query

    type=cq:Page
     property=jcr:content/cq:tags
     property.value=myTagNamespace:myTag
    
  • Zoekplan

    • [cq:Page] as [a] /* lucene:cqPageLucene(/oak:index/cqPageLucene) jcr:content/cq:tags:my:tag where [a].[jcr:content/cq:tags] = 'my:tag' */

Door de toevoeging van de indexRule voor jcr:content/cq:tags in de cqPageLucene-index kunnen cq:tags-gegevens op een geoptimaliseerde manier worden opgeslagen.

Wanneer een vraag met de jcr:content/cq:tags beperking wordt uitgevoerd, kan de index resultaten door waarde omhoog kijken. Dat betekent dat als 100 cq:Page knopen myTagNamespace:myTag als waarde hebben, slechts die 100 resultaten zijn teruggekeerd, en de andere 999.000 worden uitgesloten van de beperkingscontroles, die prestaties met een factor van 10.000 verbeteren.

Natuurlijk, verminderen de verdere vraagbeperkingen de in aanmerking komende resultaatreeksen en optimaliseren verder de vraagoptimalisering.

Op dezelfde manier zonder een extra indexregel voor het cq:tags bezit, zelfs zou een fulltext vraag met een beperking op cq:tags slecht presteren aangezien de resultaten van de index alle fulltext gelijken zouden terugkeren. De beperking op cq:tags wordt erna gefilterd.

Een andere oorzaak van post-index-filtreren is de Lijsten van het Toegangsbeheer die vaak tijdens ontwikkeling worden gemist. Controleer of de query geen paden retourneert die ontoegankelijk zijn voor de gebruiker. Dit kan gewoonlijk door betere inhoudsstructuur samen met het verstrekken van relevante wegbeperking op de vraag worden gedaan.

Een nuttige manier om te identificeren als de index van Lucene veel resultaten terugkeert om een zeer kleine ondergroep als vraagresultaat terug te keren is het toelaten van logboeken DEBUG voor org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex en te zien hoeveel documenten van de index worden geladen. Het aantal uiteindelijke resultaten in vergelijking met het aantal geladen documenten mag niet onevenredig zijn. Zie Logboekregistratie voor meer informatie.

na implementatie

  • Controleer error.log voor doorlopende vragen:

    • *WARN* org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed ### nodes ... consider creating an index or changing the query
  • Bezoek de AEM Prestaties van de Vraag verrichtingenconsole en verklaar langzame vragen zoekend vraagplannen die vraagbezitsbeperkingen aan de regels van het indexbezit niet oplossen.

Detecteren van query's voor grote resultaatsets

Tijdens ontwikkeling

Stel lage drempelwaarden in voor eak.queryLimitInMemory (bijv. 10000) en oak.queryLimitReads (bijv. 5000) en optimaliseer de dure vraag wanneer het raken van een UnsupportedOperationException die "de vraag leest meer dan x knopen…" zegt

Dit helpt middelintensieve vragen (d.w.z. te vermijden. niet ondersteund door een index of ondersteund door minder dekkende index). Bijvoorbeeld, zou een vraag die 1M knopen leest tot veel IO leiden, en negatief de algemene toepassingsprestaties beïnvloeden. Elke query die vanwege bovenstaande limieten mislukt, moet dus worden geanalyseerd en geoptimaliseerd.

na implementatie

  • Controleer de logboeken voor vragen die de grote knoop traversal of grote het geheugenconsumptie van de heap veroorzaken:

    • *WARN* ... java.lang.UnsupportedOperationException: The query read or traversed more than 100000 nodes. To avoid affecting other tasks, processing was stopped.
    • De query optimaliseren om het aantal doorgelopen knooppunten te verminderen
  • Controleer de logboeken voor vragen die het grote gebruik van het heapgeheugen teweegbrengen:

    • *WARN* ... java.lang.UnsupportedOperationException: The query read more than 500000 nodes in memory. To avoid running out of memory, processing was stopped
    • Optimaliseer de vraag om het gebruik van het heapgeheugen te verminderen

Voor AEM 6.0 - 6.2 versies, kunt u de drempel voor knoopsverplaatsing via parameters JVM in het AEM startmanuscript aanpassen om grote vragen te verhinderen het milieu te overbelasten. De aanbevolen waarden zijn:

  • -Doak.queryLimitInMemory=500000
  • -Doak.queryLimitReads=100000

In AEM 6.3, worden bovengenoemde 2 parameters vooraf gevormd door gebrek, en kunnen via OSGi QueryEngineSettings worden gewijzigd.

Meer informatie is beschikbaar onder: https://jackrabbit.apache.org/oak/docs/query/query-engine.html#Slow_Queries_and_Read_Limits

Afstemmen van query-prestaties

Het motto van de optimalisering van vraagprestaties in AEM is:

"Hoe meer beperkingen, hoe beter."

De volgende schetsen adviseren aanpassingen om vraagprestaties te verzekeren. Kies eerst de query, een minder opvallende activiteit en pas vervolgens, indien nodig, de indexdefinities aan.

Het aanpassen van de Verklaring van de Vraag

AEM ondersteunt de volgende querytalen:

  • Query Builder
  • JCR-SQL2
  • XPath

Het volgende voorbeeld gebruikt de Bouwer van de Vraag aangezien het de gemeenschappelijkste vraagtaal is die door AEM ontwikkelaars wordt gebruikt, nochtans zijn de zelfde principes van toepassing op JCR-SQL2 en XPath.

  1. Voeg een nodetype beperking toe zodat lost de vraag aan een bestaande Index van het Bezit van Lucene op.

    • Niet-geoptimaliseerde query

       property=jcr:content/contentType
       property.value=article-page
      
    • Geoptimaliseerde query

       type=cq:Page
       property=jcr:content/contentType
       property.value=article-page
      

    Zoekopdrachten zonder nodetype-beperking AEM het notatietype nt:base aan te nemen. Elk knooppunt in AEM is een subtype van dit type. Dit leidt in feite tot geen nodetype-beperking.

    Het plaatsen type=cq:Page beperkt deze vraag tot slechts cq:Page knopen, en lost de vraag aan AEM cqPageLucene op, die de resultaten tot een ondergroep van knopen (slechts cq:Page knopen) in AEM beperkt.

  2. Pas de nodetype van de vraag beperking zo aan de vraag aan een bestaande Index van het Bezit van Lucene.

    • Niet-geoptimaliseerde query

      type=nt:hierarchyNode
      property=jcr:content/contentType
      property.value=article-page
      
    • Geoptimaliseerde query

      type=cq:Page
      property=jcr:content/contentType
      property.value=article-page
      

    nt:hierarchyNode is het bovenliggende nodetype van cq:Page, en als jcr:content/contentType=article-page wordt aangenomen dat dit alleen via onze aangepaste toepassing op cq:Page knooppunten cq:Page wordt toegepast, retourneert deze query alleen jcr:content/contentType=article-pageknooppunten waar. Dit is echter een suboptimale beperking, omdat:

    • Andere knoop erft van nt:hierarchyNode (b.v. dam:Asset) onnodig toevoegen aan de reeks potentiële resultaten.
    • Er bestaat geen AEM-geleverde index voor nt:hierarchyNode, maar zoals er een opgegeven index voor cq:Page is.

    Het plaatsen type=cq:Page beperkt deze vraag tot slechts cq:Page knopen, en lost de vraag aan AEM cqPageLucene op, die de resultaten tot een ondergroep van knopen (slechts cq:de knopen van de Pagina) in AEM beperkt.

  3. U kunt ook de eigenschapbeperking(en) aanpassen zodat de query wordt omgezet in een bestaande eigenschappenindex.

    • Niet-geoptimaliseerde query

        property=jcr:content/contentType
        property.value=article-page
      
    • Geoptimaliseerde query

      property=jcr:content/sling:resourceType
      property.value=my-site/components/structure/article-page
      

    Als u de eigenschapbeperking wijzigt van jcr:content/contentType (een aangepaste waarde) in de bekende eigenschap sling:resourceType, kan de query worden omgezet in de eigenschapindex slingResourceType die alle inhoud indexeert door sling:resourceType.

    De indexen van het bezit (in tegenstelling tot de Indexen van het Bezit van Lucene) worden het best gebruikt wanneer de vraag niet door nodetype ontdekt, en één enkele bezitsbeperking domineert de resultaatreeks.

  4. Voeg de strengste padbeperking toe die mogelijk is voor de query. Geef bijvoorbeeld de voorkeur /content/my-site/us/en boven /content/my-site of /content/dam boven /.

    • Niet-geoptimaliseerde query

      type=cq:Page
      path=/content
      property=jcr:content/contentType
      property.value=article-page
      
    • Geoptimaliseerde query

      type=cq:Page
      path=/content/my-site/us/en
      property=jcr:content/contentType
      property.value=article-page
      

    Door de padbeperking van path=/contenttot path=/content/my-site/us/en te segmenteren, kunnen de indexen het aantal indexitems verminderen dat moet worden geïnspecteerd. Wanneer de vraag de weg zeer goed kan beperken, voorbij enkel /content of /content/dam, zorg ervoor de index evaluatePathRestrictions=true heeft.

    De indexgrootte wordt groter als u evaluatePathRestrictions gebruikt.

  5. Vermijd, waar mogelijk, vraagfuncties/verrichtingen zoals: LIKE en fn:XXXX als de kosten worden geschaald met het aantal op beperking gebaseerde resultaten.

    • Niet-geoptimaliseerde query

      type=cq:Page
      property=jcr:content/contentType
      property.operation=like
      property.value=%article%
      
    • Geoptimaliseerde query

      type=cq:Page
      fulltext=article
      fulltext.relPath=jcr:content/contentType
      

    De voorwaarde LIKE is traag om te evalueren omdat geen index kan worden gebruikt als de tekst met een vervanging ("%…") begint. Jcr:contains condition staat het gebruiken van een fulltext index toe, en daarom verkiest. Dit vereist de opgeloste Index van het Bezit van Lucene om indexRule voor jcr:content/contentType met analayzed=true te hebben.

    Het gebruik van queryfuncties zoals fn:lowercase(..) kan moeilijker te optimaliseren zijn omdat er geen snellere equivalenten zijn (buiten complexere en opdringerige indexanalysatorconfiguraties). Het is best om andere bereikbeperkingen te identificeren om de algemene vraagprestaties te verbeteren, die de functies vereisen om op de kleinste reeks potentiële resultaten te werken mogelijk.

  6. Deze aanpassing is specifiek voor Query Builder en is niet van toepassing op JCR-SQL2 of XPath.

    Gebruik Query Builder' radenTotal wanneer de volledige set resultaten not ​ direct nodig is.

    • Niet-geoptimaliseerde query

      type=cq:Page
      path=/content
      
    • Geoptimaliseerde query

      type=cq:Page
      path=/content
      p.guessTotal=100
      

    Als de uitvoering van de query snel is maar het aantal resultaten groot is, blz. guessTotal is een kritieke optimalisering voor de vragen van de Bouwer van de Vraag.

    p.guessTotal=100 instrueert de Bouwer van de Vraag om slechts de eerste 100 resultaten te verzamelen, en een booleaanse vlag te plaatsen die erop wijst als minstens één meer resultaten bestaan (maar niet hoeveel meer, aangezien het tellen van dit aantal in vertraging zou zijn). Deze optimalisatie is niet geschikt voor het gebruik van paginering of oneindig laden, waarbij alleen een subset met resultaten incrementeel wordt weergegeven.

Bestaande indexafstemming

  1. Als de optimale query wordt omgezet in een index met eigenschappen, hoeft u niets meer te doen omdat Eigenschapindexen minimaal afstemmen.

  2. Anders, zou de vraag aan een Index van het Bezit van Lucene moeten oplossen. Als geen index kan worden opgelost, sprong aan het Creëren van een nieuwe Index.

  3. Converteer de query zo nodig naar XPath of JCR-SQL2.

    • Query Builder-query

      query type=cq:Page
      path=/content/my-site/us/en
      property=jcr:content/contentType
      property.value=article-page
      orderby=@jcr:content/publishDate
      orderby.sort=desc
      
    • XPath dat is gegenereerd op basis van query Builder

      /jcr:root/content/my-site/us/en//element(*, cq:Page)[jcr:content/@contentType = 'article-page'] order by jcr:content/@publishDate descending
      
  4. Verstrek XPath (of JCR-SQL2) aan de Generator van de Definitie van de Index van het Eik om de geoptimaliseerde definitie van de Index van het Bezit van Luceen te produceren.

    Gegenereerde definitie van eigenschappen van Luceen

    - evaluatePathRestrictions = true
    - compatVersion = 2
    - type = "lucene"
    - async = "async"
    - jcr:primaryType = oak:QueryIndexDefinition
        + indexRules
        + cq:Page
            + properties
            + contentType
                - name = "jcr:content/contentType"
                - propertyIndex = true
            + publishDate
                - ordered = true
                - name = "jcr:content/publishDate"
    
  5. Voeg de gegenereerde definitie handmatig samen in de bestaande index voor Lucene-eigenschappen op een additieve manier. Wees voorzichtig om bestaande configuraties niet te verwijderen aangezien zij kunnen worden gebruikt om aan andere vragen te voldoen.

    1. Bepaal de plaats van de bestaande Index van het Bezit van Lucene die cq:Pagina behandelt (gebruikend de Manager van de Index). In dit geval /oak:index/cqPageLucene.
    2. Identificeer de configuratiedelta tussen de geoptimaliseerde indexdefinitie (Stap 4) en de bestaande index (/eak:index/cqPageLucene?lang=nl), en voeg de ontbrekende configuraties van de geoptimaliseerde Index aan de bestaande indexdefinitie toe.
    3. Per AEM het Opnieuw indexeren Beste praktijken, of verfrist zich of herindexeert is in orde, gebaseerd op als de bestaande inhoud door deze verandering van de indexconfiguratie zal worden uitgevoerd.

Een nieuwe index maken

  1. Verifieer de vraag niet aan een bestaande Index van het Bezit van Lucene oplost. Als dit het geval is, raadpleegt u de bovenstaande sectie over afstemmen en de bestaande index.

  2. Converteer de query zo nodig naar XPath of JCR-SQL2.

    • Query Builder-query

      type=myApp:Author
      property=firstName
      property.value=ira
      
    • XPath dat is gegenereerd op basis van query Builder

      //element(*, myApp:Page)[@firstName = 'ira']
      
  3. Verstrek XPath (of JCR-SQL2) aan de Generator van de Definitie van de Index van het Eik om de geoptimaliseerde definitie van de Index van het Bezit van Luceen te produceren.

    Gegenereerde definitie van eigenschappen van Luceen

    - compatVersion = 2
    - type = "lucene"
    - async = "async"
    - jcr:primaryType = oak:QueryIndexDefinition
        + indexRules
        + myApp:AuthorModel
            + properties
            + firstName
                - name = "firstName"
                - propertyIndex = true
    
  4. Stel de geproduceerde definitie van de Index van het Bezit van Lucene op.

    Voeg de definitie van XML toe die door de Generator van de Definitie van de Index van de Eak voor de nieuwe index aan het AEM project wordt verstrekt dat de definities van de Index van het Eak (herinner, behandelt de indexdefinities van de Eik als code, aangezien de code van hen afhangt) beheert.

    Implementeer en test de nieuwe index volgens de gebruikelijke AEM ontwikkelingscyclus van de software en verifieer de vraag aan de index oplost en de vraag presteert is.

    Na de eerste implementatie van deze index, vult AEM de index met de vereiste gegevens.

Wanneer zijn index-less en traversal vragen O.K.?

Door AEM flexibele inhoudarchitectuur is het moeilijk om te voorspellen en ervoor te zorgen dat de transformaties van inhoudsstructuren in de loop der tijd niet zullen evolueren om onaanvaardbaar groot te zijn.

Zorg er daarom voor dat indexen voldoen aan query's, behalve als de combinatie van padbeperking en noType-beperking garandeert dat minder dan 20 knooppunten ooit worden doorlopen.

Hulpprogramma's voor vraagontwikkeling

Adobe ondersteund

  • Foutopsporing voor Query Builder

    • Een WebUI voor het uitvoeren van de vragen van de Bouwer van de Vraag en produceren ondersteunend XPath (voor gebruik in Verklaar de Generator van de Definitie van de Vraag of van de Index).
    • Op AEM op /libs/cq/search/content/querydebug.html
  • CRXDE Lite - Query

    • Een WebUI voor het uitvoeren van vragen XPath en JCR-SQL2.
    • AEM op /crx/de/index.jsp > Extra > Query…
  • Query uitvoeren

    • Een dashboard van Verrichtingen van de AEM dat een gedetailleerde verklaring (het plan van de Vraag, vraagtijd, en # van resultaten) voor om het even welke bepaalde vraag XPATH of JCR-SQL2 verstrekt.
  • Trage/populaire query's

    • Een dashboard AEM bewerkingen met de recente trage en populaire query's die zijn uitgevoerd op AEM.
  • Indexbeheer

    • Een AEM Verrichtingen WebUI die de indexen op de AEM instantie tonen; Hiermee kunt u beter begrijpen welke indexen al bestaan en welke indexen kunnen worden gericht of aangevuld.
  • Logboekregistratie

    • Logboekregistratie van Query Builder

      • DEBUG @ com.day.cq.search.impl.builder.QueryImpl
    • Logboek voor uitvoeren van query's

      • DEBUG @ org.apache.jackrabbit.oak.query
  • Apache Jackrabbit Query Engine Settings OSGi Config

  • NodeCounter JMX-boon

Ondersteunde community

  • Generator voor eekindexdefinitie

    • Produceer optimale Index van het Bezit van de Geluidseigenschap van XPath of JCR-SQL2 vraagverklaringen.
  • AEM Chrome-plug-in

    • De Webbrowser van Google Chrome uitbreiding die per-verzoeklogboekgegevens, met inbegrip van uitgevoerde vragen en hun vraagplannen, in de browser ontwikkelt hulpmiddelenconsole beschikbaar stelt.
    • Sling Log Tracer 1.0.2+ moet worden geïnstalleerd en ingeschakeld op AEM.

Op deze pagina