के साथ बैच आवेषण कैसे सक्षम करें मैं क्रॉस टेबल में बड़ी संख्या में इकाइयों को सम्मिलित करना चाहता हूं। ऐसा करने के लिए, मैं हाइबरनेट के बैच सम्मिलन विकल्प को सक्षम करना चाहता हूं, ताकि प्रत्येक सम्मिलन 1 में नहीं जोड़ा जाएगा, लेकिन एक समय में 20 या 50 पंक्तियां।हाइबरनेट और स्प्रिंग बूट
मैं hibernate's tutorial से परिणामों को पुन: उत्पन्न करने की कोशिश कर रहा हूं।
//Batch inserting test entities
//This code is inside transaction already, so I'm not creating a new one
entityManager.flush();
for (int i = 0; i < 30; ++i) {
Customer customer = new Customer("Customer" + i, (i + 5) * 1000, "Position " + i);
entityManager.persist(customer);
if (i % 20 == 0) {
entityManager.flush();
entityManager.clear();
}
}
entityManager.flush();
entityManager.clear();
ग्राहक वर्ग नहीं उत्पन्न आईडी है: मैं एक परीक्षण समारोह है कि सिर्फ उदाहरण की तरह, 30 ग्राहकों को सम्मिलित करने की कोशिश करेंगे बना लिया है।
@Entity
public class Customer {
@Id
private String id;
@Column
private String name;
@Column
private long salary;
@Column
private String position;
public Customer() {
}
public Customer(String name, long salary, String position) {
this.id = UUID.randomUUID().toString();
this.name = name;
this.salary = salary;
this.position = position;
}
}
जो मैं देखने की उम्मीद कर रहा हूं वह 2 सम्मिलित बयान, 20 रिकॉर्ड के लिए एक और 10 रिकॉर्ड के लिए एक है। हालांकि, जब मैं पोस्टग्रेज़ लॉग खोलता हूं, तो मुझे 30 सम्मिलित कथन दिखाई देता है, प्रत्येक में केवल 1 पंक्ति डालने लगती है। मैंने दो बार जांच की है कि पोस्टग्रेस का उपयोग करके कई पंक्तियां डालना संभव है।
मेरा मानना है कि समस्या hibernate.jdbc.batch_size 20
पैरामीटर के कारण होती है, जिसे मुझे हाइबरनेट में जाना है। हालांकि, चूंकि मैं वसंत बूट का उपयोग कर रहा हूं, मेरे पास केवल एक ही विन्यास फाइल है application.properties। इसलिए मैं यह वहाँ डालने गए हैं की कोशिश की:
hibernate.jdbc.batch_size=20
hibernate.order_inserts=true
hibernate.order_updates=true
hibernate.jdbc.batch_versioned_data=true
spring.jpa.hibernate.jdbc.batch_size=20
spring.jpa.hibernate.order_inserts=true
spring.jpa.hibernate.order_updates=true
spring.jpa.hibernate.jdbc.batch_versioned_data=true
spring.jpa.properties.hibernate.jdbc.batch_size=20
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
इस answer के अनुसार, इस के लिए पर्याप्त होना चाहिए, लेकिन मैं अपने जार के अंदर hibernate.properties
फाइल करने के लिए इन मानकों को कॉपी करने की कोशिश की और कमांड लाइन के माध्यम से पैरामीटर की आपूर्ति की है : -Dhibernate.jdbc.batch_size=20
जैसा कि इस documentation में बताया गया है।
इनमें से कोई भी मदद नहीं करता है।
मुझे अपने कोड में बैच आकार की संपत्ति पढ़ने का कोई तरीका नहीं मिल रहा है। ऐसा लगता है कि हाइबरनेट के दस्तावेज़ में उल्लिखित अधिकांश वस्तुएं वसंत बूट एप्लिकेशन में मौजूद नहीं हैं।
मैं वसंत बूट एप्लिकेशन के अंदर हाइबरनेट के बैच डालने को कैसे सक्षम कर सकता हूं?
मैं एक न्यूनतम काम कर उदाहरण जो मुद्दा reproduces बना लिया है: https://github.com/Alexey-/spring-boot-batch
व्लाड मिहाल्सिय से जवाब मिलने के मैंने महसूस किया कि हाँ, वास्तव में बैच बयान काम कर रहे हैं के बाद, कम से कम पर हाइबरनेट और जेडीबीसी स्तर।
हालांकि, पोस्टग्रेस लॉग स्वयं को बहुत ही रोचक व्यवहार दिखाते हैं: वे बैच आवेषण और सामान्य आवेषण के मामले के लगभग समान हैं।
क्या मैं शुरू में देखने के लिए कि हाइबरनेट इस तरह के बयानों का उपयोग कर किया जाएगा उम्मीद कर रहा था:
test=# INSERT INTO customer (name, position, salary, id) values ('CustomerX', 'PositionX', '1000', 'idX'), ('CUSTOMERY', 'POSITIONY', '1000', 'idY');
कौन सा उत्पादन करेगा समान रिकॉर्ड लॉग इन करें यह करने के लिए:
2015-12-15 11:43:33.238 MSK LOG: statement: INSERT INTO customer (name, position, salary, id) values ('CustomerX', 'PositionX', '1000', 'idX'), ('CUSTOMERY', 'POSITIONY', '1000', 'idY');
हालांकि, यह मामला नहीं है ।
जब बैच प्रविष्टि सक्षम है (p6spy पता चलता है कि बयान कर रहे हैं, वास्तव में, batched), postgres इस के समान लॉग उत्पादन करेगा:
2015-12-15 12:07:00.638 MSK LOG: execute <unnamed>: BEGIN
2015-12-15 12:07:00.638 MSK LOG: duration: 0.000 ms
2015-12-15 12:07:00.638 MSK LOG: duration: 0.000 ms parse <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.638 MSK LOG: duration: 0.000 ms bind <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.638 MSK DETAIL: parameters: $1 = 'Customer0', $2 = 'Position 0', $3 = '0', $4 = '9c6a86fb-c991-4e98-aa65-fa736ef67dd7'
2015-12-15 12:07:00.638 MSK LOG: execute <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.638 MSK DETAIL: parameters: $1 = 'Customer0', $2 = 'Position 0', $3 = '0', $4 = '9c6a86fb-c991-4e98-aa65-fa736ef67dd7'
2015-12-15 12:07:00.639 MSK LOG: duration: 1.000 ms
2015-12-15 12:07:00.648 MSK LOG: duration: 0.000 ms parse S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.648 MSK LOG: duration: 0.000 ms bind S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.648 MSK DETAIL: parameters: $1 = 'Customer1', $2 = 'Position 1', $3 = '10', $4 = 'c8b2669c-044a-4a4d-acbd-31c3bcd9a783'
2015-12-15 12:07:00.648 MSK LOG: execute S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.648 MSK DETAIL: parameters: $1 = 'Customer1', $2 = 'Position 1', $3 = '10', $4 = 'c8b2669c-044a-4a4d-acbd-31c3bcd9a783'
2015-12-15 12:07:00.648 MSK LOG: duration: 0.000 ms
2015-12-15 12:07:00.648 MSK LOG: duration: 0.000 ms bind S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.648 MSK DETAIL: parameters: $1 = 'Customer2', $2 = 'Position 2', $3 = '20', $4 = '1c694f41-2ce7-4ee2-a0c0-f359690506f0'
2015-12-15 12:07:00.649 MSK LOG: execute S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.649 MSK DETAIL: parameters: $1 = 'Customer2', $2 = 'Position 2', $3 = '20', $4 = '1c694f41-2ce7-4ee2-a0c0-f359690506f0'
2015-12-15 12:07:00.649 MSK LOG: duration: 0.000 ms
2015-12-15 12:07:00.649 MSK LOG: duration: 0.000 ms bind S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.649 MSK DETAIL: parameters: $1 = 'Customer3', $2 = 'Position 3', $3 = '30', $4 = '1815947d-2604-48d4-a6be-43f6905130cf'
2015-12-15 12:07:00.649 MSK LOG: execute S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.649 MSK DETAIL: parameters: $1 = 'Customer3', $2 = 'Position 3', $3 = '30', $4 = '1815947d-2604-48d4-a6be-43f6905130cf'
2015-12-15 12:07:00.649 MSK LOG: duration: 0.000 ms
2015-12-15 12:07:00.649 MSK LOG: duration: 0.000 ms bind S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.649 MSK DETAIL: parameters: $1 = 'Customer4', $2 = 'Position 4', $3 = '40', $4 = 'cc521007-820f-4d58-8e1a-16a166aa91cf'
2015-12-15 12:07:00.649 MSK LOG: execute S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:07:00.649 MSK DETAIL: parameters: $1 = 'Customer4', $2 = 'Position 4', $3 = '40', $4 = 'cc521007-820f-4d58-8e1a-16a166aa91cf'
2015-12-15 12:07:00.649 MSK LOG: duration: 0.000 ms
... the rest of the logs is identical and do not provide any valuable information...
और जब बैच बयान विकलांग (p6spy से पता चलता है कि कोई बैचिंग किया जाता है) कर रहे हैं , लॉग इस तरह दिखता होगा:
2015-12-15 12:09:00.246 MSK LOG: execute <unnamed>: BEGIN
2015-12-15 12:09:00.246 MSK LOG: duration: 0.000 ms
2015-12-15 12:09:00.246 MSK LOG: duration: 0.000 ms parse <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.246 MSK LOG: duration: 0.000 ms bind <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.246 MSK DETAIL: parameters: $1 = 'Customer0', $2 = 'Position 0', $3 = '0', $4 = '9e085ad0-437f-4d7d-afaa-e342e031cbee'
2015-12-15 12:09:00.246 MSK LOG: execute <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.246 MSK DETAIL: parameters: $1 = 'Customer0', $2 = 'Position 0', $3 = '0', $4 = '9e085ad0-437f-4d7d-afaa-e342e031cbee'
2015-12-15 12:09:00.246 MSK LOG: duration: 0.000 ms
2015-12-15 12:09:00.248 MSK LOG: duration: 0.000 ms parse <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.248 MSK LOG: duration: 0.000 ms bind <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.248 MSK DETAIL: parameters: $1 = 'Customer1', $2 = 'Position 1', $3 = '10', $4 = 'f29cfa40-7d24-49a6-ae5d-2a2021932d80'
2015-12-15 12:09:00.248 MSK LOG: execute <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.248 MSK DETAIL: parameters: $1 = 'Customer1', $2 = 'Position 1', $3 = '10', $4 = 'f29cfa40-7d24-49a6-ae5d-2a2021932d80'
2015-12-15 12:09:00.249 MSK LOG: duration: 1.000 ms
2015-12-15 12:09:00.250 MSK LOG: duration: 0.000 ms parse <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.250 MSK LOG: duration: 0.000 ms bind <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.250 MSK DETAIL: parameters: $1 = 'Customer2', $2 = 'Position 2', $3 = '20', $4 = '067dd6d4-5060-467f-b533-75994ecbaedc'
2015-12-15 12:09:00.250 MSK LOG: execute <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.250 MSK DETAIL: parameters: $1 = 'Customer2', $2 = 'Position 2', $3 = '20', $4 = '067dd6d4-5060-467f-b533-75994ecbaedc'
2015-12-15 12:09:00.250 MSK LOG: duration: 0.000 ms
2015-12-15 12:09:00.250 MSK LOG: duration: 0.000 ms parse <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.250 MSK LOG: duration: 0.000 ms bind <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.251 MSK DETAIL: parameters: $1 = 'Customer3', $2 = 'Position 3', $3 = '30', $4 = '7df32327-f2f5-4011-848d-55aafb3f09fa'
2015-12-15 12:09:00.251 MSK LOG: execute <unnamed>: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.251 MSK DETAIL: parameters: $1 = 'Customer3', $2 = 'Position 3', $3 = '30', $4 = '7df32327-f2f5-4011-848d-55aafb3f09fa'
2015-12-15 12:09:00.251 MSK LOG: duration: 0.000 ms
2015-12-15 12:09:00.251 MSK LOG: duration: 0.000 ms parse S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.251 MSK LOG: duration: 0.000 ms bind S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.251 MSK DETAIL: parameters: $1 = 'Customer4', $2 = 'Position 4', $3 = '40', $4 = '1e55ab6a-8780-4c8f-8af2-2886d954f819'
2015-12-15 12:09:00.251 MSK LOG: execute S_1: insert into customer (name, position, salary, id) values ($1, $2, $3, $4)
2015-12-15 12:09:00.251 MSK DETAIL: parameters: $1 = 'Customer4', $2 = 'Position 4', $3 = '40', $4 = '1e55ab6a-8780-4c8f-8af2-2886d954f819'
2015-12-15 12:09:00.251 MSK LOG: duration: 0.000 ms
... the rest of the logs is identical and do not provide any valuable information...
तो, दोनों के बीच फर्क सिर्फ इतना है जब बैच अक्षम है, postgres छोटा सा अधिक समय को एहसास है कि यह तैयार बयान पुनः उपयोग करना चाहिए ले जाएगा है।
इसलिए मैंने इसकी पुष्टि करने के लिए प्रदर्शन परीक्षण चलाने का फैसला किया।
मैंने खाली डेटाबेस में 30,000 रिकॉर्ड डालने का प्रयास किया।
बैचिंग अक्षम होने के साथ, इसमें 334ms लगे।
बैचिंग सक्षम होने के साथ, इसमें 4650ms लगे!
तो मैंने इकाई मैनेजर.फ्लश (केवल इकाई प्रबंधक को छोड़कर) को सभी कॉल हटा दिए और समय 320ms तक गिर गया। मुझे नहीं पता कि क्यों हाइबरनेट के ट्यूटोरियल फ्लश का उपयोग करने की सलाह देते हैं। मुझे लगता है कि यह सिर्फ एक गलती है।
तो मुझे लगता है कि नीचे की रेखा यह है: बैचिंग काम कर रही है, लेकिन यह कोई वास्तविक लाभ प्रदान नहीं करती है (कम से कम पोस्टग्रेस के लिए)। इसके अलावा, इसे अनुचित रूप से उपयोग करना (ट्यूटोरियल में) एक भयानक, भयानक परिणाम हो सकता है। अपने जोखिम पर प्रयोग करें और हमेशा वास्तविक प्रदर्शन वृद्धि को मापें।
क्या आपने पुष्टि की है कि आपका जेडीबीसी ड्राइवर बैच डीडीएल संचालन का समर्थन करता है?जबकि डेटाबेस इसका समर्थन कर सकता है, यदि आपके ड्राइवर का संस्करण नहीं है, तो इसका कोई प्रभाव नहीं पड़ेगा। – Naros
हां, जेडीबीसी चालक बैच का समर्थन करता है। – Alexey
अपनी 'ग्राहक' कक्षा जोड़ें। आप स्प्रिंग बूट का उपयोग कर रहे हैं, इसलिए आपका 'spring.jpa.properties' वह है जिसे आप उपयोग करना चाहिए, अन्य बहुत बेकार हैं। –