Detectando Consultas Sem Índice
Durante o desenvolvimento
Explicar all consultas e garantir que seus planos de query não contenham a variável /* traverse explicação. Exemplo de plano de consulta de percurso:
- PLANO:
[nt:unstructured] as [a] /* traverse "/content//*" where ([a].[unindexedProperty] = 'some value') and (isdescendantnode([a], [/content])) */
Pós-implantação
-
Monitore o
error.log
para consultas transversais sem índice:*INFO* org.apache.jackrabbit.oak.query.QueryImpl Traversal query (query without index) ... ; consider creating and index
- Essa mensagem só será registrada se nenhum índice estiver disponível e se a consulta potencialmente atravessar muitos nós. As mensagens não são registradas se um índice estiver disponível, mas a quantidade de travamento é pequena e, portanto, rápida.
-
Visite o AEM Desempenho da consulta console de operações e Explicar consultas lentas que procuram traversal ou nenhuma explicação de consulta de índice.
Detecção de Consultas Mal Restritas
Durante o desenvolvimento
Explicar todas as consultas e garantir que elas sejam resolvidas em um índice ajustado para corresponder às restrições de propriedade da consulta.
- A cobertura do plano de consulta ideal tem
indexRules
para todas as restrições de propriedade e, no mínimo, para as restrições de propriedade mais restritas no query. - Consultas que classificam resultados devem ser resolvidas para um Índice de propriedades do Lucene com regras de índice para as propriedades classificadas por
orderable=true.
Por exemplo, o padrão cqPageLucene
não tem uma regra de índice para jcr:content/cq:tags
Antes de adicionar a regra de índice cq:tags
-
cq:tags Regra de índice
- Não existe imediatamente
-
Query Builder
type=cq:Page property=jcr:content/cq:tags property.value=my:tag
-
Plano de consulta
[cq:Page] as [a] /* lucene:cqPageLucene(https://experienceleague.adobe.com/oak:index/cqPageLucene?lang=pt-BR) *:* where [a].[jcr:content/cq:tags] = 'my:tag' */
Esse query resolve o cqPageLucene
índice, mas porque não existe nenhuma regra de índice de propriedade para jcr:content
ou cq:tags
, quando essa restrição é avaliada, cada registro no cqPageLucene
índice é verificado para determinar uma correspondência. Isso significa que se o índice contiver 1 milhão cq:Page
nós, então 1 milhão de registros são verificados para determinar o conjunto de resultados.
Após adicionar a regra de índice cq:tags
-
cq:tags Regra de índice
/oak:index/cqPageLucene/indexRules/cq:Page/properties/cqTags @name=jcr:content/cq:tags @propertyIndex=true
-
Query Builder
type=cq:Page property=jcr:content/cq:tags property.value=myTagNamespace:myTag
-
Plano de consulta
[cq:Page] as [a] /* lucene:cqPageLucene(https://experienceleague.adobe.com/oak:index/cqPageLucene?lang=pt-BR) jcr:content/cq:tags:my:tag where [a].[jcr:content/cq:tags] = 'my:tag' */
A adição de indexRule para jcr:content/cq:tags
no cqPageLucene
o índice permite cq:tags
dados a serem armazenados de forma otimizada.
Quando um query com a variável jcr:content/cq:tags
for executada, o índice poderá procurar resultados por valor. Isso significa que se 100 cq:Page
nós myTagNamespace:myTag
como valor, apenas esses 100 resultados são retornados e os outros 999.000 são excluídos das verificações de restrição, melhorando o desempenho em um fator de 10.000.
É claro que outras restrições de query reduzem os conjuntos de resultados qualificados e otimizam ainda mais a otimização de query.
Da mesma forma, sem uma regra de índice adicional para a variável cq:tags
propriedade, até mesmo uma consulta de texto completo com uma restrição em cq:tags
teria um desempenho ruim, pois os resultados do índice retornariam todas as correspondências de texto completo. A restrição em cq:tags seria filtrada depois.
Outra causa da filtragem pós-índice são as Listas de Controle de Acesso que geralmente são perdidas durante o desenvolvimento. Tente garantir que a consulta não retorne caminhos que possam estar inacessíveis ao usuário. Isso geralmente pode ser feito por uma melhor estrutura de conteúdo, juntamente com a disponibilização de uma restrição de caminho relevante na query.
Uma maneira útil de identificar se o índice Lucene está retornando muitos resultados para retornar um subconjunto muito pequeno como resultado de query é ativar logs DEBUG para org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex
e veja quantos documentos estão sendo carregados do índice. O número de eventuais resultados versus o número de documentos carregados não deve ser desproporcionado. Para obter mais informações, consulte Registro.
Pós-implantação
-
Monitore o
error.log
para consultas transversais:*WARN* org.apache.jackrabbit.oak.spi.query.Cursors$TraversingCursor Traversed ### nodes ... consider creating an index or changing the query
-
Visite o AEM Desempenho da consulta console de operações e Explicar consultas lentas que procuram planos de consulta que não resolvem restrições de propriedade de consulta para regras de propriedade de índice.
Detectando Consultas de Conjunto de Resultados Grandes
Durante o desenvolvimento
Defina limites baixos para oak.queryLimitInMemory (por exemplo, 10000) e oak.queryLimitReads (por exemplo, 5000) e otimizar a consulta cara ao hit de um UnsupportedOperationException dizendo "A consulta leu mais de x nós…"
Isso ajuda a evitar consultas que consomem muitos recursos (ou seja, não é suportada por qualquer índice ou pelo índice de cobertura inferior). Por exemplo, uma consulta que lê nós 1M levaria a muitas E/S e afetaria negativamente o desempenho geral do aplicativo. Portanto, qualquer query que falhe devido a limites acima deve ser analisada e otimizada.
Pós-implantação
-
Monitore os logs para consultas que acionam grande passagem de nó ou grande consumo de memória heap :
*WARN* ... java.lang.UnsupportedOperationException: The query read or traversed more than 100000 nodes. To avoid affecting other tasks, processing was stopped.
- Otimizar a consulta para reduzir o número de nós atravessados
-
Monitore os logs para consultas que acionam grande consumo de memória heap :
*WARN* ... java.lang.UnsupportedOperationException: The query read more than 500000 nodes in memory. To avoid running out of memory, processing was stopped
- Otimizar a consulta para reduzir o consumo de memória heap
Para AEM versões 6.0 - 6.2, você pode ajustar o limite para a travessia do nó por meio de parâmetros da JVM no script de início de AEM para impedir que consultas grandes sobrecarreguem o ambiente. Os valores recomendados são :
-Doak.queryLimitInMemory=500000
-Doak.queryLimitReads=100000
No AEM 6.3, os 2 parâmetros acima são pré-configurados por padrão e podem ser modificados por meio do QueryEngineSettings do OSGi.
Mais informações disponíveis em : https://jackrabbit.apache.org/oak/docs/query/query-engine.html#Slow_Queries_and_Read_Limits
Ajuste do desempenho da consulta
O lema da otimização de desempenho de consulta no AEM é:
"Quanto mais restrições, melhor."
A seguir, são apresentados os ajustes recomendados para garantir o desempenho da consulta. Primeiro ajuste a consulta, uma atividade menos intrusiva e, em seguida, se necessário, ajuste as definições de índice.
Ajustando a Instrução de Consulta
AEM suporta os seguintes idiomas de consulta:
- Query Builder
- JCR-SQL2
- XPath
O exemplo a seguir usa o Query Builder como a linguagem de consulta mais comum usada por AEM desenvolvedores, no entanto, os mesmos princípios são aplicáveis a JCR-SQL2 e XPath.
-
Adicione uma restrição do tipo de nó para que a consulta resolva para um Índice de propriedades do Lucene existente.
-
Consulta não otimizada
property=jcr:content/contentType property.value=article-page
-
Consulta otimizada
type=cq:Page property=jcr:content/contentType property.value=article-page
Consultas sem uma força de restrição de tipo de nó AEM assumir a variável
nt:base
nodetype, que cada nó no AEM é um subtipo de, resultando efetivamente em nenhuma restrição de tipo de nó.Configuração
type=cq:Page
restringe esta consulta somentecq:Page
e resolve a consulta para AEM cqPageLucene, limitando os resultados a um subconjunto de nós (somentecq:Page
nós) em AEM. -
-
Ajuste a restrição do tipo de nó da consulta para que ela seja resolvida para um Índice de propriedades Lucene existente.
-
Consulta não otimizada
type=nt:hierarchyNode property=jcr:content/contentType property.value=article-page
-
Consulta otimizada
type=cq:Page property=jcr:content/contentType property.value=article-page
nt:hierarchyNode
é o tipo de nó principal decq:Page
e assumindojcr:content/contentType=article-page
é aplicado somente acq:Page
nós via nosso aplicativo personalizado, esta consulta retornará somentecq:Page
nós ondejcr:content/contentType=article-page
. No entanto, essa é uma restrição subideal, pois:- Outro nó herda de
nt:hierarchyNode
(por exemplo,dam:Asset
) adicionar desnecessariamente ao conjunto de resultados potenciais. - Não existe um índice fornecido AEM para
nt:hierarchyNode
, no entanto, como há um índice fornecido paracq:Page
.
Configuração
type=cq:Page
restringe esta consulta somentecq:Page
e resolve a consulta para AEM cqPageLucene, limitando os resultados a um subconjunto de nós (somente nós cq:Page) em AEM. -
-
Ou ajuste as restrições de propriedade para que a consulta resolva para um Índice de propriedades existente.
-
Consulta não otimizada
property=jcr:content/contentType property.value=article-page
-
Consulta otimizada
property=jcr:content/sling:resourceType property.value=my-site/components/structure/article-page
Alterar a restrição de propriedade de
jcr:content/contentType
(um valor personalizado) para a propriedade conhecidasling:resourceType
permite que a query resolva para o índice de propriedadeslingResourceType
que indexa todo o conteúdo porsling:resourceType
.Os índices de propriedade (em vez de Índices de propriedades do Lucene) são melhor usados quando a consulta não é discernível por tipo de nó e uma única restrição de propriedade domina o conjunto de resultados.
-
-
Adicione a restrição de caminho mais estrita possível ao query. Por exemplo, preferir
/content/my-site/us/en
over/content/my-site
ou/content/dam
over/
.-
Consulta não otimizada
type=cq:Page path=/content property=jcr:content/contentType property.value=article-page
-
Consulta otimizada
type=cq:Page path=/content/my-site/us/en property=jcr:content/contentType property.value=article-page
Escopo da restrição de caminho de
path=/content
parapath=/content/my-site/us/en
permite que os índices reduzam o número de entradas de índice que precisam ser inspecionadas. Quando a query puder restringir muito bem o caminho, além de apenas/content
ou/content/dam
, assegure-se de que o índice tenhaevaluatePathRestrictions=true
.Observe usando
evaluatePathRestrictions
aumenta o tamanho do índice. -
-
Sempre que possível, evite funções/operações de query como:
LIKE
efn:XXXX
dado que os seus custos são proporcionais ao número de resultados baseados em restrições.-
Consulta não otimizada
type=cq:Page property=jcr:content/contentType property.operation=like property.value=%article%
-
Consulta otimizada
type=cq:Page fulltext=article fulltext.relPath=jcr:content/contentType
A condição LIKE é lenta para avaliar, pois nenhum índice pode ser usado se o texto começar com um curinga ("%…'). A condição jcr:contains permite usar um índice de texto completo e, portanto, é preferível. Isso requer que o Índice de propriedades do Lucene resolvido tenha indexRule para
jcr:content/contentType
comanalayzed=true
.Uso de funções de consulta como
fn:lowercase(..)
pode ser mais difícil de otimizar, pois não há equivalentes mais rápidos (fora das configurações mais complexas e discretas do analisador de índice). É melhor identificar outras restrições de escopo para melhorar o desempenho geral da consulta, exigindo que as funções operem no menor conjunto possível de resultados potenciais. -
-
Esse ajuste é específico do Query Builder e não se aplica a JCR-SQL2 ou XPath.
Use guessTotal do construtor de consultas quando o conjunto completo de resultados for não imediatamente necessário.
-
Consulta não otimizada
type=cq:Page path=/content
-
Consulta otimizada
type=cq:Page path=/content p.guessTotal=100
Para casos em que a execução da consulta é rápida, mas o número de resultados é grande, p
guessTotal
O é uma otimização crítica para consultas do Query Builder.p.guessTotal=100
instrui o Query Builder a coletar apenas os primeiros 100 resultados e definir um sinalizador booleano indicando se existem pelo menos mais um resultado (mas não quantos mais, já que a contagem desse número resultaria em lentidão). Essa otimização se sobressai para paginação ou casos de uso de carregamento infinito, onde apenas um subconjunto de resultados é exibido de forma incremental. -
Ajuste de índice existente
-
Se a consulta ideal for resolvida para um Índice de propriedades, não há mais nada para fazer, pois os Índices de propriedades são minimamente ajustáveis.
-
Caso contrário, a consulta deve ser resolvida para um Índice de propriedades do Lucene. Se nenhum índice puder ser resolvido, vá para Criação de um novo Índice.
-
Conforme necessário, converta a consulta para XPath ou JCR-SQL2.
-
Query Builder
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 gerado da consulta do Query Builder
/jcr:root/content/my-site/us/en//element(*, cq:Page)[jcr:content/@contentType = 'article-page'] order by jcr:content/@publishDate descending
-
-
Forneça o XPath (ou JCR-SQL2) para Gerador de definição de índice Oak para gerar a definição otimizada do Índice de propriedades do Lucene.
Definição de índice de propriedade do Lucene gerada
- 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"
-
Mescle manualmente a definição gerada no Índice de propriedades do Lucene existente de forma aditiva. Tenha cuidado para não remover configurações existentes, pois elas podem ser usadas para atender a outros queries.
- Localize o Índice de propriedades do Lucene existente que abrange cq:Page (usando o Gerenciador de índices). Nesse caso,
/oak:index/cqPageLucene
. - Identifique o delta de configuração entre a definição de índice otimizada (Etapa 4) e o índice existente (https://experienceleague.adobe.com/oak:index/cqPageLucene?lang=pt-BR) e adicione as configurações ausentes do Índice otimizado à definição de índice existente.
- De acordo com AEM Práticas recomendadas de reindexação, uma atualização ou reindexação está em ordem, com base em se o conteúdo existente será afetado por essa alteração de configuração de índice.
- Localize o Índice de propriedades do Lucene existente que abrange cq:Page (usando o Gerenciador de índices). Nesse caso,
Criar um novo índice
-
Verifique se a consulta não resolve um Índice de propriedades do Lucene existente. Se isso acontecer, consulte a seção acima sobre ajuste e índice existente.
-
Conforme necessário, converta a consulta para XPath ou JCR-SQL2.
-
Query Builder
type=myApp:Author property=firstName property.value=ira
-
XPath gerado da consulta do Query Builder
//element(*, myApp:Page)[@firstName = 'ira']
-
-
Forneça o XPath (ou JCR-SQL2) para Gerador de definição de índice Oak para gerar a definição otimizada do Índice de propriedades do Lucene.
Definição de índice de propriedade do Lucene gerada
- compatVersion = 2 - type = "lucene" - async = "async" - jcr:primaryType = oak:QueryIndexDefinition + indexRules + myApp:AuthorModel + properties + firstName - name = "firstName" - propertyIndex = true
-
Implante a definição do Índice de propriedades do Lucene gerado.
Adicione a definição XML fornecida pelo Gerador de Definição de Índice Oak para o novo índice ao projeto AEM que gerencia as definições de índice Oak (lembre-se de tratar as definições de índice Oak como código, já que o código depende delas).
Implante e teste o novo índice seguindo o ciclo de vida normal de desenvolvimento de software AEM e verifique se a consulta resolve o índice e se a consulta é executada.
Após a implantação inicial desse índice, o AEM preencherá o índice com os dados necessários.
Quando as consultas de índice e travessia estão corretas?
Devido a AEM arquitetura de conteúdo flexível, é difícil prever e garantir que as travessias das estruturas de conteúdo não evoluam ao longo do tempo para serem inaceitavelmente grandes.
Portanto, verifique se um índice atende a queries, exceto se a combinação de restrição de caminho e restrição de tipo de nó garantir que menos de 20 nós já foram atravessados.
Ferramentas de desenvolvimento de consultas
Adobe Suportado
-
Query Builder Debugger
- Uma WebUI para executar consultas do Query Builder e gerar o XPath de suporte (para uso em Explain Query ou Oak Index Definition Generator).
- Localizado em AEM em /libs/cq/search/content/querydebug.html
-
CRXDE Lite - Ferramenta de consulta
- Uma WebUI para executar consultas XPath e JCR-SQL2.
- Localizado em AEM em /crx/de/index.jsp > Ferramentas > Consulta…
-
- Um painel de Operações de AEM que fornece uma explicação detalhada (Plano de consulta, tempo de consulta e número de resultados) para qualquer consulta XPATH ou JCR-SQL2 específica.
-
- Um painel AEM Operations listando as consultas lentas e populares recentes executadas em AEM.
-
- Uma WebUI AEM Operations exibindo os índices na instância AEM; facilita a compreensão de quais índices já existem, podem ser direcionados ou aumentados.
-
-
Registro do construtor de consultas
DEBUG @ com.day.cq.search.impl.builder.QueryImpl
-
Log de execução da consulta Oak
DEBUG @ org.apache.jackrabbit.oak.query
-
-
Configuração OSGi das configurações do mecanismo de consulta Apache Jackrabbit
- Configuração do OSGi que configura o comportamento de falha para consultas de percurso.
- Localizado em AEM em /system/console/configMgr#org.apache.jackrabbit.oak.query.QueryEngineSettingsService
-
Mbean JMX NodeCounter
- MBean JMX usado para estimar o número de nós em árvores de conteúdo em AEM.
- Localizado em AEM em /system/console/jmx/org.apache.jackrabbit.oak%3Aname%3DnodeCounter%2Ctype%3DNodeCounter
Comunidade suportada
-
Gerador de definição de índice Oak
- Gere o índice ideal de propriedades do Lucence a partir das instruções de consulta XPath ou JCR-SQL2.
-
- A extensão do navegador da Web Google Chrome que expõe os dados de log por solicitação, incluindo consultas executadas e seus planos de query, no console de ferramentas dev do navegador.
- Exige Sling Log Tracer 1.0.2+ para ser instalado e ativado no AEM.