Hibernate: batch_size? Cache de segundo nível?
-
19-09-2019 - |
Pergunta
Eu tenho um objeto de domínio Hibernate que é carregado por diferentes partes da aplicação. Às vezes é vantajoso carga preguiçoso cada associação e outros, é melhor carregar a coisa inteira em uma junção. Como compromisso espero feliz que eu encontrei:
Usando busca em lote, o Hibernate pode carregar diversos proxies não inicializados se um proxy é acessado. A busca em lote é uma otimização do seleto estratégia de busca preguiçoso.
hibernate.default_batch_fetch_size
:
Usando busca em lote, o Hibernate pode carregar diversos proxies não inicializados se um proxy é acessado. A busca em lote é uma otimização do preguiçoso selecionar estratégia de busca.
Eu também ver:
hibernate.jdbc.fetch_size
:
Um valor diferente de zero determina o JDBC buscar tamanho (chama Statement.setFetchSize ()).
Bem é suficiente inteligente Hibernate para olhar no cache de segundo nível ao fazer a busca em lote? i Execute uma busca para a chamada inicial para a associação e, em seguida, as próximas chamadas X atingiu o cache? Dessa forma eu posso ter o carregamento lento que eu desejo, mas também atingiu o cache muitas vezes para o mais volume semelhante transações.
Se todo o conteúdo da coleção já está contido no cache, seria ainda executar as consultas fetching no acesso da coleção?
Graças.
Solução
Eu fiz um monte de investigação hoje e foi capaz de desenterrar uma resposta à minha pergunta. Eu estava olhando através do código Hibernate e os olhares de fluxo como este:
é a coleção inicializada?
- Não? Não um lote fetch (itens obtidos por lote-busca são colocados no cache)
- Sim? Olhada no cache para o item em particular, se ele não está lá fazer um lote-busca.
Portanto, se o item na coleção que você está procurando é encontrado em cache, em seguida, o lote-busca não acontece. Se o item não for encontrado no cache de segundo nível, em seguida, o lote buscar acontece, mas ele vai fazer uma busca de itens em lote, independentemente dos itens em lote estão no cache.
----- ----- EXEMPLO 1
O Bom:
(Três itens de uma coleção - tamanho de lote de 3) O primeiro movimento:
- collection.getItem (0) - No esconderijo | batch-busca 3 itens
- collection.getItem (1) - no carregado por lote-fetch
- collection.getItem (2) - no carregado por lote-fetch
Agora, em outro lugar, mais tarde no tempo:
- collection.getItem (0) - Hit Cache
- collection.getItem (1) - Hit Cache
- collection.getItem (2) - Hit Cache
----- ----- EXEMPLO 2
A Bad:
(Três itens de uma coleção - tamanho de lote de 3)
Neste caso, o item no índice 0 foi removido do cache porque talvez o cache estava cheio e que o item foi descartado, ou o item passou obsoleto ou inativo.
- collection.getItem (0) - Not In Cache Então Do lote de 3 (??? Select * onde id in (,))
- collection.getItem (1) - Em cache já (substituído por lote-busca de qualquer maneira)
- collection.getItem (2) - Em cache já (substituído por lote-busca de qualquer maneira)
Assim, o trade-off aqui é que você terá menos chamadas SQL devido à dosagem, mas você vai estar faltando o cache com mais frequência. Há uma passagem aberta para ter o olhar de lotes no cache de segundo nível antes que ele vai para o banco de dados.
http://opensource.atlassian.com/projects/hibernate/browse / HHH-1775
Vote!