DuckDB თუ SQLite: სწრაფ ანალიტიკას პატარა მოთხოვნებზე ფარული ფასი აქვს

|ავტორი: QUASA-ს სარედაქციო გუნდი|5 წთ საკითხავი
DuckDB თუ SQLite: სწრაფ ანალიტიკას პატარა მოთხოვნებზე ფარული ფასი აქვს

თუ ლოკალური აპი ძირითადად გასაღებით პოულობს ჩანაწერებს და მცირე ცვლილებებს ინახავს, SQLite უფრო შესაფერისი საწყისი არჩევანია. თუ მთავარი საქმე დიდი ცხრილის სკანირება, დაჯგუფება და აგრეგაციაა, უპირატესობა DuckDB-ს აქვს. ფართო ანალიტიკურ მოთხოვნაზე მოგებას ფასი აქვს მაშინ, როცა იმავე ძრავას ხშირი მოკლე ძებნებისთვის იყენებთ: ასეთ ოპერაციაში მთლიანი დაყოვნება შეიძლება გაიზარდოს.

ამიტომ ძრავის არჩევისას მონაცემთა მოცულობასთან ერთად მოთხოვნის ფორმაც გაითვალისწინეთ. გაარკვიეთ, მოთხოვნა რამდენ ჩანაწერს ეხება, სჭირდება თუ არა ინდექსი, რამდენად ხშირად იცვლება მონაცემები და რამდენი ჩაწერა უნდა შესრულდეს ერთდროულად. პასუხი ზოგჯერ ორი სამუშაოს გამიჯვნაცაა: ტრანზაქციული მონაცემების შენახვა SQLite-ში და მათი პერიოდული ანალიზი DuckDB-ში.

მცირე ინდექსირებული ძებნის რეალური დაყოვნება

GTFS-ის მონაცემებში ცალკეული მგზავრობის მოძებნა SQLite-ისა და DuckDB-ის მცირე მოთხოვნების შედარებას ასახავს.

ერთი იდენტიფიკატორით ჩანაწერის პოვნისას წასაკითხი მონაცემი მცირეა, ამიტომ მთელ დროში მოთხოვნის მომზადების, შესრულების დაწყებისა და პასუხის დაბრუნების წილი იზრდება. ფართო სკანირებისთვის შექმნილი არქიტექტურა ასეთ ოპერაციაში უპირატესობას თავისთავად ვერ იძლევა. თუ აპი თითო მომხმარებლის მოქმედებაზე მოკლე SQL მოთხოვნას უშვებს, მნიშვნელოვანია ერთი პასუხის დაყოვნება და არა მხოლოდ ის, რამდენ მონაცემს ამუშავებს ძრავა ხანგრძლივ ანგარიშში.

ლუკას ბართის GTFS მონაცემებზე ჩატარებულ შედარებაში გერმანიის ტრანსპორტის trips ცხრილიდან პირველადი გასაღებით ერთი ჩანაწერის დაბრუნებას SQLite-ში საშუალოდ 0,063 მილიწამი, DuckDB-ში კი 0,927 მილიწამი დასჭირდა. იმავე გაზომვაში ინდექსის გარეშე ფართო წაკითხვისას მიმართულება შეიცვალა და DuckDB უფრო სწრაფი აღმოჩნდა. ეს კონკრეტული Python სკრიპტის, იმდროინდელი ვერსიების, წინასწარ გახურებული ქეშისა და შერჩეული SQL მოთხოვნების შედეგია; ციფრების სხვა აპზე პირდაპირ გადატანა გაუმართლებელია.

DuckDB-ს ინდექსის გამოყენება შეუძლია: მისი ინდექსირების გზამკვლევი აღწერს ART ინდექსს, რომელიც ზოგ ძალიან შერჩევით ერთსვეტიან მოთხოვნას აჩქარებს. მრავალსვეტიანი ინდექსი ინდექსური სკანირებისთვის შეუფერებელია, ხოლო ინდექსის შენარჩუნება ცვლილებებს ამძიმებს. ეს განსხვავება მნიშვნელოვანია, როცა აპი, მაგალითად, შეკვეთას კომბინირებული გასაღებით ეძებს: ინდექსის არსებობა ჯერ კიდევ არ ნიშნავს, რომ ორივე ძრავა ერთსა და იმავე გეგმას აირჩევს.

ფართო სკანირება და აგრეგაცია სხვა სამუშაოა

საზოგადოებრივი ტრანსპორტის მრავალი მგზავრობის ერთობლივი ხედვა ანალიტიკური სკანირების მასშტაბს აჩვენებს.

ანგარიშში, რომელიც ბევრი სტრიქონიდან მხოლოდ საჭირო სვეტებს კითხულობს და შედეგს აჯგუფებს, განმსაზღვრელი ხდება დიდი მოცულობის გავლა და გამოთვლა. SQLite მწკრივზე ორიენტირებულ B-tree შენახვასა და შესრულებას ეყრდნობა; DuckDB ანალიტიკისთვის სვეტურ შენახვას, ვექტორიზებულ დამუშავებასა და პარალელურ შესრულებას იყენებს. ამიტომ დიდი სკანირების შედეგი მცირე ინდექსირებული ძებნის შედეგისგან ბუნებრივად განსხვავდება.

რეცენზირებული SQLite-ისა და DuckDB-ის კვლევის SSB გაზომვებში DuckDB ყველა ანალიტიკურ მოთხოვნაზე უფრო სწრაფი იყო, მაგრამ უპირატესობა მოთხოვნების ჯგუფის მიხედვით იცვლებოდა: ერთ ჯგუფში 3–8-ჯერ, მეორეში 30–50-ჯერ. Raspberry Pi-ზე SQLite-ის ყველაზე სწრაფ და ყველაზე ნელ SSB მოთხოვნას შორის დაახლოებით ათმაგი სხვაობა იყო, DuckDB-ის შემთხვევაში — დაახლოებით სამმაგი. ტესტამდე ცხრილები წინასწარ წაიკითხეს და ორივე ძრავას სტატისტიკის შეგროვების საშუალება ჰქონდა; ეს პირობები ცივი გაშვების დაყოვნებას არ ასახავს.

იმავე კვლევის ტრანზაქციულ TATP დატვირთვაში, სადაც მცირე ძებნა და ცვლილებები ერთმანეთს ენაცვლებოდა, SQLite-ის WAL რეჟიმმა DuckDB-ზე მაღალი გამტარუნარიანობა აჩვენა. ერთსა და იმავე ნაშრომში სამუშაოს ფორმის შეცვლით უპირატესობაც შეიცვალა. Python პროცესისთვის, რომელიც პერიოდულად აჯამებს დიდ ფაქტების ცხრილს, SSB ახლო ანალოგია; პროცესისთვის, რომელიც თითო მოთხოვნაზე მხოლოდ ერთ შეკვეთას აბრუნებს, უფრო ახლოა ინდექსირებული ძებნა.

ჩაწერის რეჟიმი და საერთო ფაილი

ტრანზაქციული აპის არჩევანში წაკითხვის დრო მხოლოდ ერთი განზომილებაა. SQLite-ის გამოყენების ოფიციალური განმარტება ამბობს, რომ მონაცემთა ბაზის ერთ ფაილზე ერთდროულად ერთი ჩამწერი მუშაობს, დანარჩენები კი რიგში დგებიან. მოკლე ტრანზაქციებისთვის ეს ხშირად მისაღებია; თუ მრავალი პროცესი ერთდროულ ჩაწერას მოითხოვს და ლოდინი მიუღებელია, დოკუმენტაცია კლიენტ–სერვერულ ძრავას ურჩევს. იგივე რეკომენდაცია ეხება მრავალი კომპიუტერიდან საერთო ფაილთან პირდაპირ მუშაობას.

აქ განსხვავდება მომხმარებელთა რაოდენობა და ერთ ფაილზე ჩაწერის კონკურენცია. ლოკალურ აპს შეიძლება ბევრი წაკითხვა ჰქონდეს, მაგრამ ცვლილებები მოკლე და იშვიათი იყოს; ასეთ შემთხვევაში ჩამწერის შეზღუდვა გადაწყვეტილებას შესაძლოა არ ცვლიდეს. სხვა სისტემაში ხანგრძლივი ჩაწერის ტრანზაქციები მოთხოვნებს დააყოვნებს, მაშინაც კი, თუ ცალკე გაშვებული წაკითხვის ტესტი შესანიშნავ დროს აჩვენებს.

DuckDB განსაკუთრებით შეესაბამება დატვირთვას, სადაც მონაცემები პარტიებად იტვირთება და შემდეგ ანალიტიკური კითხვები დომინირებს. თუ პროდუქტი მუდმივად იღებს მცირე ცვლილებებს და დაუყოვნებლივ აბრუნებს ცალკეულ ჩანაწერებს, ტრანზაქციული დატვირთვა ცალკე უნდა შეფასდეს. მხოლოდ ანალიტიკური გაზომვა ვერ გვეტყვის, როგორ მოიქცევა აპი ჩაწერის რიგში ან რა დაყოვნება ექნება თითო მომხმარებლის მოქმედებას.

რას ზომავს შედარება და რას ტოვებს გარეთ

Raspberry Pi-ზე ჩატარებული SQLite-ისა და DuckDB-ის გაზომვები აჩვენებს, რატომ არის ტესტის პირობები მნიშვნელოვანი.

ერთი და იმავე SQL მოთხოვნის დრო პირობებზეა დამოკიდებული: მონაცემები შეიძლება მეხსიერებაში იყოს ან დისკიდან იკითხებოდეს, ინდექსი უკვე აგებული იყოს ან მის შექმნას დრო სჭირდებოდეს. შედეგის Python-ში გადმოტანა, ცხრილის შემოტანა და პირველი გაშვების ხარჯიც საბოლოო სამუშაო ციკლის ნაწილია. ამიტომ მხოლოდ გახურებული აგრეგაციის დრო ყველა ტიპის ადგილობრივ აპს ვერ აღწერს.

DuckDB-ის გაზომვების ოფიციალური გზამკვლევი პირდაპირ მიუთითებს, რომ სისტემებს შორის სამართლიანი შედარება რთულია: მისი TPC-H და LDBC მაგალითები შესაბამის მონაცემებსა და ზოგ მოთხოვნას იყენებს, მაგრამ ოფიციალურ TPC ან LDBC შედეგებს არ წარმოადგენს და განახლებების მსგავს ნაწილებს გამოტოვებს. ასეთი გაზომვა ანალიტიკური დამუშავების შესაძლებლობას ხსნის, თუმცა აპის ჩაწერის რეჟიმზე პირდაპირ პასუხს არ იძლევა.

ბართის ტესტსა და SSB გაზომვას განსხვავებული მონაცემები, მოწყობილობები და მოთხოვნები აქვთ, ამიტომ მათი კოეფიციენტები ერთმანეთს პირდაპირ არ ედრება. პირველში განსაკუთრებით ნათლად ჩანს ერთი ჩანაწერის მოძებნისა და არაინდექსირებული წაკითხვის დაპირისპირება; მეორეში — რთული ანალიტიკური ჯგუფების სხვაობა. არჩევანისთვის არსებითი კონკრეტული მილიწამების დამახსოვრება კი არა, იმის დანახვაა, რომ შედეგის მიმართულებას მოთხოვნის ფორმა ცვლის.

არჩევანი მოთხოვნის ფორმის მიხედვით

თუ სამუშაოს ძირითადი ნაწილი გასაღებით ძებნა, ცალკეული ჩანაწერის განახლება და მოკლე ტრანზაქციაა, SQLite ბუნებრივი საწყისი არჩევანია. თუ ჭარბობს დიდი ფაქტების ცხრილის გავლა, მრავალი სტრიქონის დაჯგუფება ან პერიოდული ანგარიში, DuckDB უფრო შესაბამისი საწყისი არჩევანია. აქ „დიდი“ მარტო ფაილის ზომას არ ნიშნავს: არსებითია, მოთხოვნა მისი რა წილის წაკითხვას აიძულებს ძრავას.

შერეულ დატვირთვაში შეიძლება SQLite იყოს სამუშაო ჩანაწერების საცავი, DuckDB კი მათგან მიღებული მონაცემების ანალიტიკური ფენა. ამ სქემას საკუთარი ფასი აქვს: მონაცემების გადატანის დრო, განახლების პერიოდულობა და პასუხის სიძველე. თუ ანგარიში თითქმის მყისიერად განახლებულ მონაცემს მოითხოვს, ეს ფასი შეიძლება უფრო მნიშვნელოვანი იყოს, ვიდრე ცალკე აგრეგაციის სიჩქარე.

საბოლოო არჩევანს სამი განსხვავებული შეკითხვა აყალიბებს: რამდენად სწრაფად ბრუნდება მოკლე ინდექსირებული პასუხი, რამდენ ხანს გრძელდება ფართო ანგარიში და რამდენი ჩაწერა ელოდება რიგში. ამ მაჩვენებლებს ერთი „ყველაზე სწრაფი ბაზა“ ვერ ჩაანაცვლებს; მათგან ჩანს, რომელი ძრავა შეესაბამება აპის ძირითად სამუშაოს და სად ჩნდება გამიჯვნის ღირებულება.

ასევე წაიკითხეთ:

გაზიარება:

გამოიწერეთ ჩვენი ბიულეტენი

მიიღეთ უახლესი ამბები Web3-ის, AI-სა და კრიპტოს შესახებ პირდაპირ თქვენს ელფოსტაზე.

0