3 gyakori hibernált teljesítményprobléma és hogyan lehet megtalálni őket a naplófájlban

1. Bemutatkozás

Valószínűleg elolvasta a hibernált állapot rossz teljesítményével kapcsolatos panaszokat, esetleg maga is küzdött valamennyivel. Már több mint 15 éve használom a Hibernate funkciót, és több mint elég problémába ütköztem.

Az évek során megtanultam, hogy ezek a problémák elkerülhetők, és hogy sok mindent megtalál a naplófájljában. Ebben a bejegyzésben szeretném megmutatni, hogyan találhat meg és javíthat ki közülük 3-at.

2. Keresse meg és javítsa ki a teljesítményproblémákat

2.1. Naplózza az SQL utasításokat a termelésben

Az első előadási kérdést rendkívül könnyű észrevenni, és gyakran figyelmen kívül hagyják. Ez az SQL utasítások naplózása termelési környezetben.

Néhány napló utasítás megírása nem hangzik nagy dolognak, és sok olyan alkalmazás létezik, amelyek pontosan ezt teszik. De rendkívül hatástalan, főleg via System.out.println ahogy Hibernate teszi, ha beállítja a show_sql paraméter a hibernált konfigurációban a igaz:

Hibernálás: select order0_.id id1_2_, order0_.orderNumber orderNum2_2_, order0_.version version3_2_ from purchaseOrder order0_ Hibernate: select items0_.order_id as order_id4_0_0_, items0_.id as id1_0_0_, items___id_______id_ items0_.product_id mint product_5_0_1_, items0_.quantity as mennyiség2_0_1_, items0_.version version3_0_1_ from OrderItem items0_ where items0_.order_id =? Hibernálás: válasszon item0_.order_id mint order_id4_0_0_, items0_.id mint id1_0_0_, items0_.id mint id1_0_1_, items0_.order_id mint order_id4_0_1_, items0_.product_id mint product_5_0_1_, items0_______0__________0__ mennyiség_ order_id =? Hibernálás: válasszon item0_.order_id mint order_id4_0_0_, items0_.id mint id1_0_0_, items0_.id mint id1_0_1_, items0_.order_id mint order_id4_0_1_, items0_.product_id mint product_5_0_1_, items0_______0___________ mennyiség_ order_id =?

Az egyik projektemben 20% -kal javítottam a teljesítményt néhány percen belül a beállítással show_sql nak nek hamis. Ilyen eredményről szeretnél beszámolni a következő stand-up találkozón 🙂

Nagyon nyilvánvaló, hogyan lehet megoldani ezt a teljesítményproblémát. Csak nyissa meg a konfigurációt (pl. Persistence.xml fájlját), és állítsa be a show_sql paraméter a hamis. A gyártás során egyébként nincs szüksége ezekre az információkra.

De szükségük lehet rájuk a fejlesztés során. Ha nem, akkor 2 különböző hibernált konfigurációt használ (amit nem szabad), és deaktiválta az SQL utasítás naplózását is. Ennek megoldása az, hogy 2 különböző napló konfigurációt használunk a fejlesztéshez és a gyártáshoz, amelyek optimalizálva vannak a futásidejű környezet speciális követelményeinek.

Fejlesztési konfiguráció

A fejlesztőkonfigurációnak a lehető legtöbb hasznos információt kell tartalmaznia, hogy lássa, miként hat a Hibernate az adatbázisra. Ezért legalább a létrehozott SQL utasításokat naplóznia kell a fejlesztői konfigurációban. Ezt aktiválásával teheti meg HIBÁK üzenet a org.hibernate.SQL kategória. Ha meg szeretné tekinteni a kötési paraméterek értékeit is, akkor meg kell adnia a napló szintjét org.hibernate.type.descriptor.sql nak nek NYOM:

log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =% d {HH: mm: ss, SSS}% -5p [% c] -% m% n log4j.rootLogger = információ, stdout # alapszintű naplószint minden üzenethez log4j.logger.org.hibernate = info # SQL utasítások és paraméterek log4j.logger.org.hibernate.SQL = hibakeresés log4j.logger.org.hibernate.type.descriptor.sql = nyom

Az alábbi kódrészlet néhány naplóüzenetet mutat, amelyeket a hibernálás ezzel a naplókonfigurációval ír. Amint láthatja, részletes információkat kap a végrehajtott SQL lekérdezésről, valamint az összes beállított és lekért paraméterértékről:

23: 03: 22,246 HIBAKeresés SQL: 92 - válassza a order0_.id elemet id1_2_, order0_.orderNumber értéket orderNum2_2_, order0_.version verzióként3_2_ a purchaseOrder rendelés0_ ahol order0_.id = 1 23: 03: 22,254 TRACE BasicExtractor: 61 - kibontott érték ( [id1_2_]: [BIGINT]) - [1] 23: 03: 22,261 TRACE BasicExtractor: 61 - kivont érték ([orderNum2_2_]: [VARCHAR]) - [order1] 23: 03: 22,263 TRACE BasicExtractor: 61 - kibontott érték ( [version3_2_]: [INTEGER]) - [0]

A hibernálás sokkal több belső információt nyújt a Ülés ha aktiválja a hibernált statisztikákat. Ezt a rendszer tulajdonságának beállításával teheti meg hibernate.generate_statistics igazra.

De kérem, csak a fejlesztési vagy tesztkörnyezetére vonatkozó statisztikákat aktiválja. Ezen információk összegyűjtése lelassítja az alkalmazást, és maga is létrehozhatja a teljesítményproblémáit, ha ezt aktiválja a gyártásban.

Néhány statisztikai példát láthat a következő kódrészletben:

23: 04: 12,123 INFO StatisticalLoggingSessionEventListener: 258 - Munkamutatók {23793 nanoszekundumot költöttek 1 JDBC kapcsolat megszerzésére; 0 nanoszekundum költött 0 JDBC kapcsolat felszabadítására; 394686 nanoszekundum fordult 4 JDBC utasítás elkészítésére; 2528603 nanoszekundum költött 4 JDBC utasítás végrehajtására; 0 nanoszekundum költött 0 JDBC köteg végrehajtására; 0 nanoszekundum költött 0 L2C put végrehajtására; 0 nanoszekundum költött 0 L2C találat végrehajtására; 0 nanoszekundum költött 0 L2C hiányzás végrehajtására; 9700599 nanoszekundumot 1 öblítés végrehajtására fordítottak (összesen 9 entitás és 3 gyűjtemény öblítésével); 42921 nanoszekundum töltött 1 részöblítés végrehajtásával (0 entitás és 0 gyűjtemény öblítése)}

Rendszeresen használom ezeket a statisztikákat a mindennapi munkám során, hogy megtaláljam a teljesítményproblémákat, még mielőtt azok a termelésben jelentkeznének, és erről több bejegyzést is írhatnék. Tehát csak a legfontosabbakra összpontosítsunk.

A 2–5. Sor megmutatja, hogy a Hibernate hány JDBC kapcsolatot és utasítást használt ezen munkamenet során, és mennyi időt töltött rá. Mindig át kell néznie ezeket az értékeket, és össze kell hasonlítania az elvárásaival.

Ha sokkal több állítás van, mint amire számítottál, akkor valószínűleg a leggyakoribb teljesítményprobléma, az n + 1 kiválasztási probléma jelentkezik. Szinte minden alkalmazásban megtalálható, és hatalmas teljesítményproblémákat okozhat egy nagyobb adatbázisban. Ezt a kérdést a következő szakaszban részletezem.

A 7–9. Sor megmutatja, hogy a Hibernate hogyan lépett kapcsolatba a 2. szintű gyorsítótárral. Ez a Hibernate 3 gyorsítótárának egyike, és munkamenetektől függetlenül tárolja az entitásokat. Ha az alkalmazásában a 2. szintet használja, mindig figyelnie kell ezeket a statisztikákat, hogy a hibernált állapotba kerüljenek-e az entitások.

Gyártási konfiguráció

A gyártási konfigurációt a teljesítményre kell optimalizálni, és kerülni kell a sürgősen nem szükséges üzeneteket. Általában ez azt jelenti, hogy csak a hibaüzeneteket kell naplóznia. A Log4j használata esetén ezt a következő konfigurációval érheti el:

A Log4j használata esetén ezt a következő konfigurációval érheti el:

log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =% d {HH: mm: ss, SSS}% -5p [% c] -% m% n log4j.rootLogger = információ, stdout # alapszintű naplószint minden üzenetnél log4j.logger.org.hibernate = hiba

2.2. N + 1 Válassza a Kiadás lehetőséget

Mint már kifejtettem, az n + 1 select kérdés a leggyakoribb teljesítményprobléma. Sok fejlesztő hibáztatja az OR-Mapping koncepciót ebben a kérdésben, és nem tévednek teljesen. De könnyen elkerülheti, ha megérti, hogy a Hibernate hogyan kezeli a lustán elárult kapcsolatokat. Ezért a fejlesztő is hibás, mert az ő felelőssége elkerülni az ilyen jellegű problémákat. Tehát hadd magyarázzam el először, hogy miért létezik ez a probléma, majd mutassak meg egy egyszerű módszert annak megakadályozására. Ha már ismeri az n + 1 kiválasztott kérdéseket, akkor közvetlenül a megoldáshoz ugorhat.

A hibernálás nagyon kényelmes feltérképezést biztosít az entitások közötti kapcsolatok számára. Csak meg kell adnia egy attribútumot a kapcsolódó entitás típusával és néhány megjegyzéssel annak meghatározásához:

@Entity @Table (name = "purchaseOrder") public class Order végrehajtja a Serializable {@OneToMany (mappedBy = "order", fetch = FetchType.LAZY) privát készlet elemeket = new HashSet (); ...}

Amikor most betölt egy Rendelés elemet az adatbázisból, csak meg kell hívnia a getItems () módszer a rendelés összes elemének megszerzéséhez. A hibernálás elrejti a szükséges adatbázis-lekérdezéseket a kapcsolódó információk megszerzéséhez OrderItem entitások az adatbázisból.

Amikor a Hibernate programmal kezdett, valószínűleg megtanulta, hogy használnia kell FetchType.LAZY a kapcsolatok többségében, és hogy ez az alapértelmezés a sok kapcsolathoz. Ez azt mondja a Hibernate-nek, hogy csak akkor töltse le a kapcsolódó entitásokat, ha a kapcsolatot feltérképező attribútumot használja. Csak a szükséges adatok beolvasása általában jó dolog, de a Hibernate számára további lekérdezés végrehajtására is szükség van az egyes kapcsolatok inicializálásához. Ez rengeteg lekérdezést eredményezhet, ha az entitások listáján dolgozik, mint én a következő kódrészletben:

Lista megrendelések = em.createQuery ("SELECT o FROM Order o"). GetResultList (); for (Rendelési sorrend: megrendelések) {log.info ("Rendelés:" + megrendelés.getOrderNumber ()); log.info ("Tételek száma:" + order.getItems (). size ()); }

Valószínűleg nem számíthat arra, hogy ez a néhány kódsor több száz vagy akár több ezer adatbázis-lekérdezést hozhat létre. De igen, ha használja FetchType.LAZY a OrderItem entitás:

22: 47: 30,065 DEBUG SQL: 92 - válassza a order0_.id azonosítóként id1_2_, order0_.orderNumber értéket orderNum2_2_, order0_.version verzióként_23__ a orderOrder order0_ 22: 47: 30,136 INFO NamedEntityGraphTest: 58 - Rendelés: order1 22: 47: 30,140 DEUG SQL: 92 - select items0_.order_id mint order_id4_0_0_, items0_.id mint id1_0_0_, items0_.id mint id1_0_1_, items0_.order_id mint order_id4_0_1_, items0_.product_id as product_5_0_1_, items0_.quotity as mennyiség0_0 items0_.order_id =? 22: 47: 30 171 INFO NamedEntityGraphTest: 59 - Tételek száma: 2 22: 47: 30,171 INFO NamedEntityGraphTest: 58 - Rendelés: order2 22: 47: 30,172 DEBUG SQL: 92 - select items0_.order_id as order_id4_0_0_, items0_.id as id1 , items0_.id mint id1_0_1_, items0_.order_id mint order_id4_0_1_, items0_product_id mint product_5_0_1_, items0_.quantity mint mennyiség2_0_1_, items0_.version as version3_0_1_ from OrderItem items0_ where items0_.order_id =? 22: 47: 30 174 INFO NamedEntityGraphTest: 59 - Tételek száma: 2 22: 47: 30,174 INFO NamedEntityGraphTest: 58 - Megrendelés: order3 22: 47: 30,174 DEBUG SQL: 92 - select items0_.order_id as order_id4_0_0_, items0_.id as id1 , items0_.id mint id1_0_1_, items0_.order_id mint order_id4_0_1_, items0_product_id mint product_5_0_1_, items0_.quantity mint mennyiség2_0_1_, items0_.version as version3_0_1_ from OrderItem items0_ where items0_.order_id =? 22: 47: 30 176 INFO NamedEntityGraphTest: 59 - Tételek száma: 2

A hibernálás egyetlen lekérdezést hajt végre az összes megszerzéséhez Rendelés entitások és egy-egy további az n-hez Rendelés entitások a orderItem kapcsolat. Tehát most már tudja, miért hívják ezt a fajta problémát n + 1 select kérdésnek, és miért okozhatnak hatalmas teljesítményproblémákat.

Még rosszabbá teszi, hogy gyakran nem ismeri fel egy kis tesztadatbázisban, ha nem ellenőrizte a hibernált állapot statisztikáit. A kódrészlet csak néhány tucat lekérdezést igényel, ha a tesztadatbázis nem tartalmaz sok megrendelést. De ez egészen más lesz, ha a produktív adatbázist használja, amely több ezeret tartalmaz.

Korábban mondtam, hogy könnyedén elkerülheti ezeket a kérdéseket. És ez igaz. Csak ki kell inicializálnia a orderItem kapcsolatot, amikor kiválasztja a Rendelés entitások az adatbázisból.

De kérem, csak akkor tegye meg, ha használja a kapcsolatot az üzleti kódban, és nem használja FetchType.EAGER hogy mindig lekérje a kapcsolódó entitásokat. Ez csak az n + 1 problémát helyettesíti egy másik teljesítményproblémával.

Kapcsolatok inicializálása a @NévEntityGraph

A kapcsolatok inicializálásához többféle lehetőség áll rendelkezésre. Inkább a @NévEntityGraph ami a JPA 2.1-ben bemutatott egyik kedvenc funkcióm. Ez egy lekérdezésfüggetlen módszert biztosít az entitások grafikonjának megadásához, amelyeket a hibernálásnak be kell hoznia az adatbázisból. A következő kódrészletben láthat egy példát egy egyszerű grafikonra, amely lehetővé teszi, hogy a hibernált állapot lelkesen lehívja egy entitás elemattribútumát:

@Entity @Table (name = "purchase_order") @NamesEntityGraph (name = "graph.Order.items", attributeNodes = @NamedAttributeNode ("items")) public class Order végrehajtja Serializable {...}

Nem sokat kell tennie, hogy meghatározzon egy entitásdiagramot a-val @NévEntityGraph annotáció. Csak meg kell adnia egy egyedi nevet a grafikonnak és egyet @NévAttributeNode minden egyes attribútumhoz a hibernálás lelkesen fog letölteni. Ebben a példában csak a items attribútum térképezi fel az an közötti kapcsolatot Rendelés és több OrderItem entitások.

Most az entitásdiagram segítségével szabályozhatja a lekérési viselkedést vagy egy adott lekérdezést. Ezért be kell állítania egy EntityGraph alapján @NévEntityGraph definícióját, és utalásként adja meg a EntityManager.find () módszer vagy a lekérdezés. Ezt a következő kódrészletben teszem meg, ahol kiválasztom a Rendelés 1. azonosítóval rendelkező entitás az adatbázisból:

EntityGraph gráf = this.em.getEntityGraph ("graph.Order.items"); Térképtippek = új HashMap (); hints.put ("javax.persistence.fetchgraph", grafikon); adja vissza ezt: em.find (Rend.osztály, 1 L, tippek);

A hibernálás ezen információk felhasználásával létrehoz egy SQL utasítást, amely megkapja a Rendelés entitás és az entitásdiagram attribútumai az adatbázisból:

17: 34: 51,310 HIBAKERETÉS [org.hibernate.loader.plan.build.spi.LoadPlanTreePrinter] (pool-2-thread-1) LoadPlan (entitás = blog.oughts.on.java.jpa21.entity.graph.model. Rendelés) - Visszatér - EntityReturnImpl (entitás = blog.butts.on.java.jpa21.entity.graph.model.Rendelés, querySpaceUid =, elérési út = blog.oughts.on.java.jpa21.entity.graph.model.Order) - CollectionAttributeFetchImpl (gyűjtemény = blog.oughts.on.java.jpa21.entity.graph.model.Order.items, querySpaceUid =, elérési út = blog.oughts.on.java.jpa21.entity.graph.model.Order.items) - (gyűjteményelem) CollectionFetchableElementEntityGraph (entitás = blog.butts.on.java.jpa21.entity.graph.model.OrderItem, querySpaceUid =, elérési út = blog.oughts.on.java.jpa21.entity.graph.model.Order. elemek.) - EntityAttributeFetchImpl (entitás = blog.butts.on.java.jpa21.entity.graph.model.Product, querySpaceUid =, elérési út = blog.oughts.on.java.jpa21.entity.graph.model.Order.items ..product) - QuerySpaces - EntityQuerySpaceImpl (uid =, entitás = blog.oughts.on.java.jpa21.entity.graph.model .Order) - SQL tábla álnevek leképezése - order0_ - alias utótag - 0_ - utótag kulcsoszlopok - {id1_2_0_} - JOIN (JoinDefinedByMetadata (elemek)): -> - CollectionQuerySpaceImpl (uid =, gyűjtemény = blog.oughts.on.java. jpa21.entity.graph.model.Order.items) - SQL tábla álnevek leképezése - items1_ - álnév utótag - 1_ - utótagolt kulcsoszlopok - {order_id4_2_1_} - entitás-elem alias utótag - 2_ - 2_entity-element utótaggal ellátott kulcsoszlopok - id1_0_2_ - JOIN (JoinDefinedByMetadata (elemek)): -> - EntityQuerySpaceImpl (uid =, entitás = blog.oughts.on.java.jpa21.entity.graph.model.OrderItem) - SQL tábla álnevek leképezése - items1_ - alias utótag - 2_ - utótag kulcsoszlopok - {id1_0_2_} - CSATLAKOZÁS (JoinDefinedByMetadata (termék)): -> - EntityQuerySpaceImpl (uid =, entitás = blog.butts.on.java.jpa21.entity.graph.model.Product) - SQL táblázat álnevének leképezése - product2_ - alias utótag - 3_ - utótag kulcsoszlopok - {id1_1_3_} 17: 34: 51,311 DEBUG [org.hibernate.loader.entity.plan.EntityLoader] (pool-2-thread-1) Static select f vagy entitás blog. , items1_.id mint id1_0_1_, items1_.id mint id1_0_2_, items1_.order_id mint order_id4_0_2_, items1_.product_id mint product_5_0_2_, items1_.quantity as mennyiség2_0_2_, items1_.version as version3_0_2_, product2__name_2 .version as version3_1_3_ from purchase_order order0_ bal külső csatlakozás OrderItem items1_ on order0_.id = items1_.order_id bal külső csatlakozás Product product__ on items1_.product_id = product2_.id where order0_.id =?

Csak egy kapcsolat inicializálása elég jó egy blogbejegyzéshez, de egy valós projektben valószínűleg komplexebb grafikonokat szeretne készíteni. Tehát tegyük meg.

Természetesen megadhat egy tömböt @NévAttributeNode annotációk ugyanazon entitás több attribútumának lekéréséhez, és használhatja @NamesSubGraph az entitások további szintjének lekérési viselkedésének meghatározása. Ezt a következő kódrészletben használom nemcsak az összes kapcsolódó lekérésére OrderItem szervezetek, hanem a Termék entitás mindegyikhez OrderItem:

@Entity @Table (name = "purchase_order") @NévEntityGraph (name = "graph.Order.items", attributeNodes = @NamedAttributeNode (value = "items", subgraph = "items"), subgraphs = @NamesSubgraph (name = " items ", attributeNodes = @NévAttributeNode (" termék "))) public class A rendelés végrehajtja a Serializable {...}

Amint láthatja, az a meghatározása @NamesSubGraph nagyon hasonlít az a meghatározásához @NévEntityGraph. Ezután hivatkozhat erre az algráfra a @NévAttributeNode annotáció az adott attribútum lekérési viselkedésének meghatározásához.

Ezeknek a kommentároknak a kombinációja lehetővé teszi összetett entitásdiagramok definiálását, amelyek segítségével inicializálhatja az összes felhasználási esetben használt kapcsolatot, és elkerülheti az n + 1 kiválasztott problémákat. Ha futás közben dinamikusan meg szeretné adni az entitásdiagramját, akkor ezt egy Java API-n keresztül is megteheti.

2.3. Frissítse az entitásokat egyesével

Az entitások egyesével történő frissítése nagyon természetesnek tűnik, ha objektumorientált módon gondolkodik. Csak megkapja a frissíteni kívánt entitásokat, és néhány szetter metódust hív meg az attribútumainak megváltoztatásához, mint bármely más objektummal.

Ez a megközelítés jól működik, ha csak néhány entitást változtat meg.De nagyon hatékonnyá válik, ha az entitások listájával dolgozik, és ez a harmadik teljesítményprobléma, amelyet könnyen észrevehet a naplófájljában. Csak meg kell keresnie egy csomó SQL UPDATE utasítást, amelyek teljesen ugyanúgy néznek ki, mint a következő naplófájlban láthatja:

22: 58: 05,829 DEBUG SQL: 92 - válassza a product0_.id nevet id1_1_, a product0_.name nevet2_1_, a product0_.price árként3_1_, a product0_.version verzióként4_1_ a Product product0_ 22-ből: 58: 05,883 DEBUG SQL: 92 - frissítse a termékkészletet név = ?, ár = ?, verzió =? ahol id =? és verzió =? 22: 58: 05,889 HIBAKeresés SQL: 92 - frissítés Termékkészlet neve = ?, price = ?, version =? ahol id =? és verzió =? 22: 58: 05,891 HIBAKeresés SQL: 92 - frissítse a termékkészlet nevét = ?, price = ?, version =? ahol id =? és verzió =? 22: 58: 05,893 HIBAKeresés SQL: 92 - frissítse a termékkészlet nevét = ?, price = ?, version =? ahol id =? és verzió =? 22: 58: 05,900 HIBAKeresés SQL: 92 - frissítse a termékkészlet nevét = ?, price = ?, version =? ahol id =? és verzió =?

Az adatbázis-rekordok relációs reprezentációja sokkal jobban illik ezekhez a felhasználási esetekhez, mint az objektumorientált. Az SQL segítségével egyszerűen írhat egy SQL utasítást, amely frissíti az összes módosítani kívánt rekordot.

Ugyanezt teheti a hibernált móddal is, ha JPQL-t, natív SQL-t vagy a CriteriaUpdate API-t használ. Mind a 3 nagyon hasonló, ezért használjuk a JPQL-t ebben a példában.

Hasonló módon definiálhat egy JPQL UPDATE utasítást, mint azt az SQL-ből ismeri. Csak meg kell határoznia, hogy mely entitást szeretné frissíteni, hogyan változtassa meg az attribútumainak értékeit, és korlátozza az érintett entitásokat a WHERE utasításban.

Példa erre a következő kódrészletben, ahol 10% -kal növelem az összes termék árát:

em.createQuery ("UPDATE Product p SET p.price = p.price * 0.1"). executeUpdate ();

A hibernálás létrehoz egy SQL UPDATE utasítást a JPQL utasítás alapján, és elküldi azt az adatbázisnak, amely végrehajtja a frissítési műveletet.

Nagyon nyilvánvaló, hogy ez a megközelítés sokkal gyorsabb, ha hatalmas számú entitást kell frissítenie. De van egy hátránya is. A hibernált állapot nem tudja, mely entitásokat érinti a frissítési művelet, és nem frissíti az 1. szintű gyorsítótárat. Ezért ügyeljen arra, hogy ne olvasson és frissítsen egy entitást JPQL utasítással ugyanazon a hibernált munkameneten belül, vagy le kell választania, hogy eltávolítsa a gyorsítótárból.

3. Összefoglalás

Ezen a poszton belül megmutattam neked 3 Hibernált teljesítményproblémák, amelyek megtalálhatók a naplófájlokban.

Közülük kettőt hatalmas számú SQL utasítás okozott. Ez a teljesítményproblémák gyakori oka, ha a hibernált rendszerrel dolgozik. A hibernálás elrejti az adatbázis hozzáférését az API mögött, és ez gyakran megnehezíti az SQL utasítások tényleges számának kitalálását. Ezért mindig ellenőrizze a végrehajtott SQL utasításokat, amikor módosítja a tartóssági szintjét.