MariaDB
 sql >> डेटाबेस >  >> RDS >> MariaDB

बैकएंड प्रदर्शन में सुधार भाग 2/3:डेटाबेस इंडेक्स का उपयोग करना

डेटाबेस इंडेक्स डेवलपर्स की चिंता का विषय हैं। उनके पास बैकएंड में SQL क्वेरी का उपयोग करने वाली खोज और फ़िल्टर सुविधाओं के प्रदर्शन में सुधार करने की क्षमता है। लेखों की इस श्रृंखला के दूसरे भाग में, मैं स्प्रिंग बूट और वाडिन के साथ विकसित जावा वेब एप्लिकेशन का उपयोग करके फ़िल्टर को तेज़ करने में डेटाबेस इंडेक्स के प्रभाव को दिखाऊंगा।

इस श्रृंखला का भाग 1 पढ़ें यदि आप सीखना चाहते हैं कि हम यहां जिस उदाहरण एप्लिकेशन का उपयोग करेंगे, वह कैसे काम करता है। आप GitHub पर कोड पा सकते हैं। साथ ही, और यदि आप चाहें, तो मैंने इस लेख का एक वीडियो संस्करण रिकॉर्ड किया है:

आवश्यकता

हमारे पास एक ग्रिड के साथ एक वेब पेज है जो मारियाडीबी डेटाबेस से पुस्तकों की एक सूची दिखाता है:

हम इस पृष्ठ के उपयोगकर्ताओं को यह देखने की अनुमति देने के लिए एक फ़िल्टर जोड़ना चाहते हैं कि कौन सी पुस्तकें किसी निश्चित तिथि पर प्रकाशित हुई थीं।

रिपोजिटरी क्वेरी और सेवा को लागू करना

प्रकाशन तिथि तक डेटा को फ़िल्टर करने का समर्थन करने के लिए हमें बैकएंड में कुछ बदलाव करने होंगे। रिपॉजिटरी क्लास में, हम निम्नलिखित विधि जोड़ सकते हैं:

@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {

    Page<Book> findByPublishDate(LocalDate publishDate, Pageable pageable);

}

यह आलसी लोडिंग का उपयोग करता है जैसा कि हमने लेखों की इस श्रृंखला के भाग 1 में देखा था। हमें इस पद्धति को लागू करने की आवश्यकता नहीं है—स्प्रिंग डेटा इसे रनटाइम पर हमारे लिए बनाएगा।

हमें सेवा वर्ग में एक नई विधि भी जोड़नी होगी (जो वह वर्ग है जिसे UI व्यावसायिक तर्क चलाने के लिए उपयोग करता है)। ऐसे:

@Service
public class BookService {

    private final BookRepository repository;

    ...

    public Stream<Book> findAll(LocalDate publishDate, int page, int pageSize) {
        return repository.findByPublishDate(publishDate, PageRequest.of(page, pageSize)).stream();
    }

}

वेब पेज में फ़िल्टर जोड़ना

प्रकाशन तिथि के अनुसार पुस्तकों के बैकएंड सहायक फ़िल्टरिंग के साथ, हम वेब पेज (या देखें) कार्यान्वयन में एक तिथि पिकर जोड़ सकते हैं:

@Route("")
public class BooksView extends VerticalLayout {

    public BooksView(BookService service) {

        ...

        var filter = new DatePicker("Filter by publish date");
        filter.addValueChangeListener(event ->
                grid.setItems(query ->
                        service.findAll(filter.getValue(), query.getPage(), query.getPageSize())
                )
        );

        add(filter, grid);
        setSizeFull();
    }

    ...
}

यह कोड सिर्फ एक नया DatePicker बनाता है वस्तु जो अपने मूल्य में परिवर्तन सुनती है (मूल्य परिवर्तन श्रोता के माध्यम से)। जब मूल्य बदलता है तो हम उपयोगकर्ता द्वारा चुनी गई तिथि पर पुस्तकों को प्रकाशित करने के लिए सेवा वर्ग का उपयोग करते हैं। फिर मेल खाने वाली पुस्तकों को Grid . के आइटम के रूप में सेट किया जाता है ।

धीमी क्वेरी का परीक्षण करना

हमने फ़िल्टर लागू कर दिया है; हालांकि, यदि आपके पास तालिका में 200 हजार पंक्तियां हैं, तो यह बेहद धीमी है। इसे अजमाएं! मैंने एक लेख लिखा है जो बताता है कि जावा अनुप्रयोगों के लिए यथार्थवादी डेमो डेटा कैसे उत्पन्न किया जाए। पंक्तियों की इस संख्या के साथ, एप्लिकेशन को मेरी मशीन पर वेब पेज पर डेटा दिखाने में कई सेकंड लग गए (मैकबुक प्रो 2,3 गीगाहर्ट्ज क्वाड-कोर इंटेल कोर i5)। यह उपयोगकर्ता के अनुभव को पूरी तरह से बर्बाद कर देता है।

"क्वेरी समझाएं" के साथ क्वेरी का विश्लेषण करना

यदि आपने क्वेरी लॉगिंग सक्षम की है, तो आप सर्वर के लॉग में हाइबरनेट द्वारा जेनरेट की गई क्वेरी ढूंढ सकते हैं। इसे कॉपी करें, प्रश्न चिह्नों को वास्तविक मानों से बदलें, और इसे SQL डेटाबेस क्लाइंट में चलाएं। वास्तव में, मैं आपका कुछ समय बचा सकता हूं। यहाँ क्वेरी का एक सरलीकृत संस्करण है:

SELECT id, author, image_data, pages, publish_date, title
FROM book
WHERE publish_date = '2021-09-02';

MariaDB में EXPLAIN . शामिल है कथन जो हमें इस बारे में उपयोगी जानकारी देता है कि इंजन कैसे अनुमान लगाता है कि क्वेरी चलाने वाला है। इसका उपयोग करने के लिए, बस EXPLAIN add जोड़ें क्वेरी से पहले:

EXPLAIN SELECT id, author, image_data, pages, publish_date, title
FROM book
WHERE publish_date = '2021-09-02';

ये रहा परिणाम:

दस्तावेज़ में वह सब कुछ है जो आपको इसके बारे में जानने की आवश्यकता है, लेकिन महत्वपूर्ण बिट प्रकार . में मान है कॉलम:सभी . यह मान हमें बताता है कि इंजन का अनुमान है कि उसे तालिका में सभी पंक्तियों को लाना या पढ़ना होगा। अच्छी बात नहीं है।

अनुक्रमणिका बनाना

सौभाग्य से, हम उस कॉलम पर एक इंडेक्स बनाकर इसे आसानी से ठीक कर सकते हैं जिसका उपयोग हम डेटा को फ़िल्टर करने के लिए कर रहे हैं:publish_date . ऐसे:

CREATE INDEX book\_publish\_date_index ON book(publish_date);

एक डेटाबेस इंडेक्स इंजन द्वारा बनाई गई एक डेटा संरचना है, आमतौर पर एक बी-ट्री (b .) संतुलित . के लिए ), और यह एक तालिका में एक निश्चित पंक्ति को खोजने की प्रक्रिया को गति देता है, अर्थात, उस पंक्ति की खोज करना जिस कॉलम में वह मान दिया गया है जिस पर सूचकांक बनाया गया है। बी-पेड़ों की प्रकृति के कारण प्रक्रिया तेज़ है—वे कुछ मामलों में समय की जटिलता को O(N) से O(log(N)) और यहां तक ​​कि O(log(1)) तक कम करने के लिए डेटा को व्यवस्थित रखते हैं।

सुधार का परीक्षण

इंडेक्स के निर्माण के साथ, हम EXPLAIN स्टेटमेंट को फिर से चला सकते हैं और देख सकते हैं कि टाइप कॉलम मान ref दिखाता है। सभी . के बजाय :

रेफरी value का अर्थ है कि जब हम क्वेरी चलाते हैं तो इंजन इंडेक्स का उपयोग करेगा। जब आप अपने अधिक जटिल प्रश्नों में अनुक्रमणिका जोड़ते हैं तो यह महत्वपूर्ण है कि आप इसकी जांच करें। हमेशा EXPLAIN का उपयोग करें जब आप कोई अनुक्रमणिका पेश करते हैं तो आप प्रदर्शन में सुधार कर रहे हैं या नहीं, इसकी दोबारा जाँच करने के लिए कथन।

यदि आप ब्राउज़र में वेब एप्लिकेशन आज़माते हैं और दिनांक पिकर में कोई अन्य दिनांक चुनते हैं (सर्वर को पुनरारंभ करने की कोई आवश्यकता नहीं है), तो आपको एक बड़ा अंतर दिखाई देगा! उदाहरण के लिए, डेटा मेरी मशीन पर एक सेकंड से भी कम समय में पुनर्प्राप्त किया जाता है, जबकि हमारे द्वारा अनुक्रमणिका बनाने के कई सेकंड पहले!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मारियाडीबी द्वारा समर्थित कोलाज की पूरी सूची

  2. मारियाडीबी में सीओटी () कैसे काम करता है?

  3. MySQL और MariaDB सुरक्षा कैसे प्राप्त करें, इस पर दस टिप्स

  4. एमएचए के साथ शीर्ष सामान्य मुद्दे और उन्हें कैसे ठीक करें

  5. Maxscale से ProxySQL लोड बैलेंसर में माइग्रेट करना