📄 performance.pot
字号:
msgstr ""#: performance.xml:1054(title) msgid "Taxonomy"msgstr ""#: performance.xml:1056(para) msgid "Hibernate defines three basic kinds of collections:"msgstr ""#: performance.xml:1060(para) msgid "collections of values"msgstr ""#: performance.xml:1063(para) msgid "one to many associations"msgstr ""#: performance.xml:1066(para) msgid "many to many associations"msgstr ""#: performance.xml:1070(para) msgid "This classification distinguishes the various table and foreign key relationships but does not tell us quite everything we need to know about the relational model. To fully understand the relational structure and performance characteristics, we must also consider the structure of the primary key that is used by Hibernate to update or delete collection rows. This suggests the following classification:"msgstr ""#: performance.xml:1081(para) msgid "indexed collections"msgstr ""#: performance.xml:1084(para) msgid "sets"msgstr ""#: performance.xml:1087(para) msgid "bags"msgstr ""#: performance.xml:1091(para) msgid "All indexed collections (maps, lists, arrays) have a primary key consisting of the <literal><key></literal> and <literal><index></literal> columns. In this case collection updates are usually extremely efficient - the primary key may be efficiently indexed and a particular row may be efficiently located when Hibernate tries to update or delete it."msgstr ""#: performance.xml:1099(para) msgid "Sets have a primary key consisting of <literal><key></literal> and element columns. This may be less efficient for some types of collection element, particularly composite elements or large text or binary fields; the database may not be able to index a complex primary key as efficently. On the other hand, for one to many or many to many associations, particularly in the case of synthetic identifiers, it is likely to be just as efficient. (Side-note: if you want <literal>SchemaExport</literal> to actually create the primary key of a <literal><set></literal> for you, you must declare all columns as <literal>not-null=\"true\"</literal>.)"msgstr ""#: performance.xml:1110(para) msgid "<literal><idbag></literal> mappings define a surrogate key, so they are always very efficient to update. In fact, they are the best case."msgstr ""#: performance.xml:1115(para) msgid "Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. Hibernate has no way of distinguishing between duplicate rows. Hibernate resolves this problem by completely removing (in a single <literal>DELETE</literal>) and recreating the collection whenever it changes. This might be very inefficient."msgstr ""#: performance.xml:1123(para) msgid "Note that for a one-to-many association, the \"primary key\" may not be the physical primary key of the database table - but even in this case, the above classification is still useful. (It still reflects how Hibernate \"locates\" individual rows of the collection.)"msgstr ""#: performance.xml:1133(title) msgid "Lists, maps, idbags and sets are the most efficient collections to update"msgstr ""#: performance.xml:1135(para) msgid "From the discussion above, it should be clear that indexed collections and (usually) sets allow the most efficient operation in terms of adding, removing and updating elements."msgstr ""#: performance.xml:1141(para) msgid "There is, arguably, one more advantage that indexed collections have over sets for many to many associations or collections of values. Because of the structure of a <literal>Set</literal>, Hibernate doesn't ever <literal>UPDATE</literal> a row when an element is \"changed\". Changes to a <literal>Set</literal> always work via <literal>INSERT</literal> and <literal>DELETE</literal> (of individual rows). Once again, this consideration does not apply to one to many associations."msgstr ""#: performance.xml:1150(para) msgid "After observing that arrays cannot be lazy, we would conclude that lists, maps and idbags are the most performant (non-inverse) collection types, with sets not far behind. Sets are expected to be the most common kind of collection in Hibernate applications. This is because the \"set\" semantics are most natural in the relational model."msgstr ""#: performance.xml:1158(para) msgid "However, in well-designed Hibernate domain models, we usually see that most collections are in fact one-to-many associations with <literal>inverse=\"true\"</literal>. For these associations, the update is handled by the many-to-one end of the association, and so considerations of collection update performance simply do not apply."msgstr ""#: performance.xml:1168(title) msgid "Bags and lists are the most efficient inverse collections"msgstr ""#: performance.xml:1170(para) msgid "Just before you ditch bags forever, there is a particular case in which bags (and also lists) are much more performant than sets. For a collection with <literal>inverse=\"true\"</literal> (the standard bidirectional one-to-many relationship idiom, for example) we can add elements to a bag or list without needing to initialize (fetch) the bag elements! This is because <literal>Collection.add()</literal> or <literal>Collection.addAll()</literal> must always return true for a bag or <literal>List</literal> (unlike a <literal>Set</literal>). This can make the following common code much faster."msgstr ""#: performance.xml:1189(title) msgid "One shot delete"msgstr ""#: performance.xml:1191(para) msgid "Occasionally, deleting collection elements one by one can be extremely inefficient. Hibernate isn't completely stupid, so it knows not to do that in the case of an newly-empty collection (if you called <literal>list.clear()</literal>, for example). In this case, Hibernate will issue a single <literal>DELETE</literal> and we are done!"msgstr ""#: performance.xml:1198(para) msgid "Suppose we add a single element to a collection of size twenty and then remove two elements. Hibernate will issue one <literal>INSERT</literal> statement and two <literal>DELETE</literal> statements (unless the collection is a bag). This is certainly desirable."msgstr ""#: performance.xml:1204(para) msgid "However, suppose that we remove eighteen elements, leaving two and then add thee new elements. There are two possible ways to proceed"msgstr ""#: performance.xml:1211(para) msgid "delete eighteen rows one by one and then insert three rows"msgstr ""#: performance.xml:1214(para) msgid "remove the whole collection (in one SQL <literal>DELETE</literal>) and insert all five current elements (one by one)"msgstr ""#: performance.xml:1219(para) msgid "Hibernate isn't smart enough to know that the second option is probably quicker in this case. (And it would probably be undesirable for Hibernate to be that smart; such behaviour might confuse database triggers, etc.)"msgstr ""#: performance.xml:1225(para) msgid "Fortunately, you can force this behaviour (ie. the second strategy) at any time by discarding (ie. dereferencing) the original collection and returning a newly instantiated collection with all the current elements. This can be very useful and powerful from time to time."msgstr ""#: performance.xml:1231(para) msgid "Of course, one-shot-delete does not apply to collections mapped <literal>inverse=\"true\"</literal>."msgstr ""#: performance.xml:1240(title) msgid "Monitoring performance"msgstr ""#: performance.xml:1242(para) msgid "Optimization is not much use without monitoring and access to performance numbers. Hibernate provides a full range of figures about its internal operations. Statistics in Hibernate are available per <literal>SessionFactory</literal>."msgstr ""#: performance.xml:1249(title) msgid "Monitoring a SessionFactory"msgstr ""#: performance.xml:1251(para) msgid "You can access <literal>SessionFactory</literal> metrics in two ways. Your first option is to call <literal>sessionFactory.getStatistics()</literal> and read or display the <literal>Statistics</literal> yourself."msgstr ""#: performance.xml:1257(para) msgid "Hibernate can also use JMX to publish metrics if you enable the <literal>StatisticsService</literal> MBean. You may enable a single MBean for all your <literal>SessionFactory</literal> or one per factory. See the following code for minimalistic configuration examples:"msgstr ""#: performance.xml:1284(para) msgid "TODO: This doesn't make sense: In the first case, we retrieve and use the MBean directly. In the second one, we must give the JNDI name in which the session factory is held before using it. Use <literal>hibernateStatsBean.setSessionFactoryJNDIName(\"my/JNDI/Name\")</literal>"msgstr ""#: performance.xml:1289(para) msgid "You can (de)activate the monitoring for a <literal>SessionFactory</literal>"msgstr ""#: performance.xml:1294(para) msgid "at configuration time, set <literal>hibernate.generate_statistics</literal> to <literal>false</literal>"msgstr ""#: performance.xml:1301(para) msgid "at runtime: <literal>sf.getStatistics().setStatisticsEnabled(true)</literal> or <literal>hibernateStatsBean.setStatisticsEnabled(true)</literal>"msgstr ""#: performance.xml:1308(para) msgid "Statistics can be reset programatically using the <literal>clear()</literal> method. A summary can be sent to a logger (info level) using the <literal>logSummary()</literal> method."msgstr ""#: performance.xml:1317(title) msgid "Metrics"msgstr ""#: performance.xml:1319(para) msgid "Hibernate provides a number of metrics, from very basic to the specialized information only relevant in certain scenarios. All available counters are described in the <literal>Statistics</literal> interface API, in three categories:"msgstr ""#: performance.xml:1326(para) msgid "Metrics related to the general <literal>Session</literal> usage, such as number of open sessions, retrieved JDBC connections, etc."msgstr ""#: performance.xml:1332(para) msgid "Metrics related to he entities, collections, queries, and caches as a whole (aka global metrics),"msgstr ""#: performance.xml:1338(para) msgid "Detailed metrics related to a particular entity, collection, query or cache region."msgstr ""#: performance.xml:1345(para) msgid "For exampl,e you can check the cache hit, miss, and put ratio of entities, collections and queries, and the average time a query needs. Beware that the number of milliseconds is subject to approximation in Java. Hibernate is tied to the JVM precision, on some platforms this might even only be accurate to 10 seconds."msgstr ""#: performance.xml:1352(para) msgid "Simple getters are used to access the global metrics (i.e. not tied to a particular entity, collection, cache region, etc.). You can access the metrics of a particular entity, collection or cache region through its name, and through its HQL or SQL representation for queries. Please refer to the <literal>Statistics</literal>, <literal>EntityStatistics</literal>, <literal>CollectionStatistics</literal>, <literal>SecondLevelCacheStatistics</literal>, and <literal>QueryStatistics</literal> API Javadoc for more information. The following code shows a simple example:"msgstr ""#: performance.xml:1379(para) msgid "To work on all entities, collections, queries and region caches, you can retrieve the list of names of entities, collections, queries and region caches with the following methods: <literal>getQueries()</literal>, <literal>getEntityNames()</literal>, <literal>getCollectionRoleNames()</literal>, and <literal>getSecondLevelCacheRegionNames()</literal>."msgstr ""#. Put one translator per line, in the form of NAME <EMAIL>, YEAR1, YEAR2.#: performance.xml:0(None) msgid "translator-credits"msgstr ""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -