मैंने भोलेपन से एक वेब सेवा लागू की, जो Json ऑब्जेक्ट्स की एक सूची का उपभोग करती है और उन्हें SQL डेटाबेस में संग्रहीत करती है springframework.data.jpa (जेपीए और हाइबरनेट)। हालांकि, समाधान का प्रदर्शन कम है और प्रोफाइलर ने मुझे संकेत दिया कि मुख्य समस्या एक-एक करके Json ऑब्जेक्ट्स से इकाइयाँ बनाने में निहित है।

नीचे दिया गया कोड सरल है, लेकिन मूल रूप से: आने वाली सूची में प्रत्येक Json ऑब्जेक्ट के लिए दो इकाइयाँ बनाई गई हैं: DataEntity और IdentityEntity। पहला ब्याज का डेटा रखता है और बाद वाले को FK के रूप में उपयोग करता है, जिसमें एक समय और एक व्यक्ति का मिश्रित PK होता है।

मैं भंडारण प्रक्रिया को तेज करना चाहता हूं। मैंने एक प्रोफाइलर के साथ निर्धारित किया है कि बहुत सारे फ्लश ऑपरेशन हैं जो प्रत्येक नई इकाई को सम्मिलित करने के बाद किए जा रहे हैं। चूंकि मुझे एक निश्चित समय में हजारों रिकॉर्ड डालने की आवश्यकता है, इससे प्रदर्शन समस्या उत्पन्न होती है। क्या मैं शायद एक लेनदेन में सम्मिलित कर सकता हूं या इसे अनुकूलित करने के अन्य तरीके क्या हैं?

डेटा वर्ग (मेरे पास कई समान वर्ग हैं):

@Entity
public class DataEntity {
    @EmbeddedId
    private IdentityEntity identity;
    private Double data;
}

एम्बेड करने योग्य इकाई:

@Embeddable
public class IdentityEntity implements Serializable {
    @NonNull
    private Long personId;
    @NonNull
    private Long datetimeId;
}

जेपीए भंडार:

@Repository
public interface DataRepository extends JpaRepository<DataEntity, IdentityEntity> {}

सरलीकृत नियंत्रक:

public class DataController{
    @Autowired
    private DataRepository dataRepository;
    @Autowired
    private DatetimeRepository datetimeRepository;

    @PostMapping("/upload")
    public void upload(...List<DataJson> items) {
        PersonEntity person = getPerson(...);          // fast enough
        for (DataJson i : items) {                 // begin transaction here?
            saveNewEntity(i, person.getId());
        }
    }

    private void saveNewEntity(DataJson json, Long personId) {
        TimeEntity savedDatetime = datetimeRepository.save(new TimeEntity(json.getDatetime()));
        IdentityEntity mi = IdentityEntity(personId, savedDatetime.getId());

        DataEntity entry = new DataEntity(mi, json.getData());
        dataRepository.save(entry);
    }
}

संपादित करें: प्रोफाइलर में और खुदाई करने के बाद, मैंने पाया है कि एक और समय लेने वाला ऑपरेशन लेनदेन प्रबंधन ही हो सकता है। हालांकि मैंने किसी भी लेनदेन व्यवहार को लागू या कॉन्फ़िगर नहीं किया है, मुझे संदेह है कि स्प्रिंग बूट में हाइबरनेट ओआरएम के लिए कुछ डिफ़ॉल्ट कॉन्फ़िगर किया गया है। मुझे लगता है कि अब लूप के प्रत्येक पुनरावृत्ति में एक लेनदेन बनाया जा रहा है, पहला प्रदर्शन मुद्दा है और दूसरा मुद्दा भी पैदा कर रहा है, जहां लेनदेन के अंत में सबकुछ फ्लश हो जाता है और डीबी में लिखा जाता है।

0
Ondrej Sotolar 5 नवम्बर 2019, 16:23

1 उत्तर

सबसे बढ़िया उत्तर

हां। SimpleJpaRepository में सभी विधियों को @Transactional के साथ एनोटेट किया गया है।

अपनी अपलोड विधि में बस एक @Transactional एनोटेशन जोड़ें।

... या

पहले सभी ऑब्जेक्ट बनाएं और save(Iterable<S> entities) विधि का उपयोग करके उन्हें एक बार में सहेजें।

1
Selindek 5 नवम्बर 2019, 20:20