PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Vladimir Sitnikovun 2016-cı ilin əvvəlində “PostgreSQL və JDBC bütün suyu sıxır” hesabatının stenoqramını oxumağı təklif edirəm.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Günortanız Xeyir Mənim adım Vladimir Sitnikovdur. Mən 10 ildir NetCracker-də işləyirəm. Mən daha çox məhsuldarlıqla məşğulam. Java ilə əlaqəli hər şey, SQL ilə əlaqəli hər şey mənim sevdiyim şeydir.

Və bu gün PostgreSQL-dən verilənlər bazası serveri kimi istifadə etməyə başladığımız zaman şirkətdə qarşılaşdığımız hadisələrdən danışacağam. Və biz əsasən Java ilə işləyirik. Amma bu gün sizə deyəcəklərim təkcə Java ilə bağlı deyil. Təcrübə göstərdiyi kimi, bu, başqa dillərdə də baş verir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Danışacağıq:

  • məlumatların seçilməsi haqqında.
  • Məlumatların saxlanması haqqında.
  • Həm də performans haqqında.
  • Və orada basdırılan sualtı dırmıqlar haqqında.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Sadə bir sualla başlayaq. Biz əsas açar əsasında cədvəldən bir sıra seçirik.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Verilənlər bazası eyni hostda yerləşir. Və bütün bu əkinçilik 20 millisaniyə çəkir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bu 20 millisaniyə çox şeydir. Əgər 100 belə sorğunuz varsa, o zaman bu sorğular arasında sürüşməyə saniyədə vaxt sərf edirsiniz, yəni biz vaxt itiririk.

Biz bunu etməyi xoşlamırıq və bunun üçün bazanın bizə nə təklif etdiyinə baxırıq. Verilənlər bazası bizə sorğuları yerinə yetirmək üçün iki seçim təklif edir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Birinci seçim sadə sorğudur. Bunun nə xeyri var? Onu götürüb göndərməyimiz, başqa heç nə.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/478

Verilənlər bazasında daha mürəkkəb, lakin daha funksional olan təkmil sorğu da var. Siz ayrı-ayrılıqda təhlil, icra, dəyişən bağlama və s. üçün sorğu göndərə bilərsiniz.

Super genişləndirilmiş sorğu cari hesabatda əhatə etməyəcəyimiz bir şeydir. Biz, ola bilsin ki, verilənlər bazasından nəsə istəyirik və hansısa formada formalaşmış bir arzu siyahısı var, yəni bizim istədiyimiz budur, amma indi və növbəti ildə mümkün deyil. Beləliklə, biz onu sadəcə qeyd etdik və əsas insanları silkələyəcəyik.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bizim edə biləcəyimiz sadə sorğu və genişləndirilmiş sorğudur.

Hər bir yanaşmanın özəlliyi nədir?

Sadə sorğu birdəfəlik icra üçün yaxşıdır. Bir dəfə bitdi və unudulub. Problem ondadır ki, o, ikili məlumat formatını dəstəkləmir, yəni bəzi yüksək performanslı sistemlər üçün uyğun deyil.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Genişləndirilmiş sorğu – təhlil zamanı vaxtınıza qənaət etməyə imkan verir. Bunu etdik və istifadə etməyə başladıq. Bu, həqiqətən, bizə kömək etdi. Yalnız təhlilə qənaət yoxdur. Məlumatların ötürülməsinə qənaət var. Məlumatların ikili formatda ötürülməsi daha səmərəlidir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Gəlin məşqə keçək. Tipik bir tətbiq belə görünür. Java ola bilər və s.

Bəyanat yaratdıq. Əmri yerinə yetirdi. Yaxın yaradılmışdır. Burada səhv haradadır? Problem nədir? Problem deyil. Bütün kitablarda belə deyilir. Bu belə yazılmalıdır. Maksimum performans istəyirsinizsə, belə yazın.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Amma təcrübə göstərdi ki, bu işləmir. Niyə? Çünki bizdə “yaxın” üsul var. Biz bunu etdikdə verilənlər bazası nöqteyi-nəzərindən məlum olur ki, bu, verilənlər bazası ilə işləyən siqaret çəkənə bənzəyir. Biz "PARSE EXECUTE DEALLOCATE" dedik.

Niyə bütün bu əlavə ifadələrin yaradılması və boşaldılması? Onlar heç kimə lazım deyil. Amma adətən PreparedStatements-də baş verənlər ondan ibarətdir ki, biz onları bağladığımız zaman verilənlər bazasında olan hər şeyi bağlayırlar. Bizim istədiyimiz bu deyil.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Biz də sağlam insanlar kimi baza ilə işləmək istəyirik. Bir dəfə ifadəmizi götürüb hazırladıq, sonra dəfələrlə icra etdik. Əslində, dəfələrlə - bu, tətbiqlərin bütün həyatında bir dəfədir - onlar təhlil edilmişdir. Və biz fərqli REST-lərdə eyni ifadə id-dən istifadə edirik. Bu, bizim məqsədimizdir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Buna necə nail ola bilərik?

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Çox sadədir - bəyanatları bağlamağa ehtiyac yoxdur. Bunu belə yazırıq: "hazırla" "icra et".

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Əgər belə bir şey işə salsaq, o zaman hardasa nəyinsə daşacağı aydındır. Əgər aydın deyilsə, cəhd edə bilərsiniz. Bu sadə metoddan istifadə edən etalon yazaq. Bəyanat yaradın. Biz onu sürücünün bəzi versiyalarında işə salırıq və tapırıq ki, o, malik olduğu bütün yaddaşın itirilməsi ilə olduqca tez çökür.

Aydındır ki, bu cür səhvlər asanlıqla düzəldilir. Mən onlar haqqında danışmayacağam. Amma deyim ki, yeni versiya çox daha sürətli işləyir. Metod axmaqdır, amma yenə də.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Necə düzgün işləmək olar? Bunun üçün nə etməliyik?

Əslində, tətbiqlər həmişə ifadələri bağlayır. Bütün kitablarda deyirlər ki, bağlayın, əks halda yaddaş sızacaq.

Və PostgreSQL sorğuları necə önbelleğe almağı bilmir. Hər bir sessiyanın özü üçün bu önbelleği yaratması lazımdır.

Biz də təhlil etməyə vaxt itirmək istəmirik.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Həmişə olduğu kimi, iki seçimimiz var.

Birinci seçim ondan ibarətdir ki, biz onu götürək və deyirik ki, gəlin hər şeyi PgSQL-ə bağlayaq. Orada bir önbellek var. Hər şeyi önbelleğe alır. Əla çıxacaq. Bunu gördük. 100500 müraciətimiz var. İşləmir. Biz sorğuların əl ilə prosedurlara çevrilməsinə razı deyilik. Yox yox.

İkinci variantımız var - götürün və özümüz kəsin. Mənbələri açıb kəsməyə başlayırıq. Gördük və gördük. Məlum oldu ki, bunu etmək o qədər də çətin deyil.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/319

Bu, 2015-ci ilin avqustunda ortaya çıxdı. İndi daha müasir versiya var. Və hər şey əladır. O qədər yaxşı işləyir ki, tətbiqdə heç nəyi dəyişmirik. Və biz hətta PgSQL istiqamətində düşünməyi dayandırdıq, yəni bu, bütün əlavə xərcləri demək olar ki, sıfıra endirmək üçün kifayət idi.

Müvafiq olaraq, hər bir birdəfəlik sorğuda verilənlər bazasında yaddaş itkisinin qarşısını almaq üçün Server tərəfindən hazırlanmış ifadələr 5-ci icrada aktivləşdirilir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Soruşa bilərsiniz - nömrələr haradadır? Nə əldə edirsən? Və burada nömrələr verməyəcəyəm, çünki hər sorğunun özünəməxsusluğu var.

Sorğularımız elə idi ki, OLTP sorğularının təhlilinə təxminən 20 millisaniyə sərf etdik. İcra üçün 0,5 millisaniyə, təhlil üçün 20 millisaniyə var idi. Sorğu – 10 KiB mətn, 170 sətir plan. Bu OLTP sorğusudur. 1, 5, 10, bəzən daha çox sətir tələb edir.

Ancaq 20 millisaniyəni heç vaxt itirmək istəmədik. Biz onu 0-a endirdik. Hər şey əladır.

Buradan nə götürə bilərsən? Əgər sizdə Java varsa, o zaman sürücünün müasir versiyasını götürüb sevinirsiniz.

Əgər başqa dildə danışırsınızsa, onda düşünün - bəlkə bu sizə də lazımdır? Çünki son dil nöqteyi-nəzərindən, məsələn, PL 8 və ya sizdə LibPQ varsa, o zaman icraya deyil, təhlilə vaxt sərf etdiyiniz sizə aydın deyil və bunu yoxlamağa dəyər. Necə? Hər şey pulsuzdur.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bundan başqa, burada səhvlər və bəzi xüsusiyyətlər var. Və biz indi onlar haqqında danışacağıq. Əksəriyyəti sənaye arxeologiyası, tapdıqlarımız, rastlaşdıqlarımız haqqında olacaq.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Əgər sorğu dinamik şəkildə yaradılıbsa. Baş verir. Kimsə sətirləri bir-birinə yapışdırır, nəticədə SQL sorğusu yaranır.

O niyə pisdir? Pisdir, çünki hər dəfə fərqli bir simlə bitiririk.

Və bu müxtəlif sətirin hashCode yenidən oxunmalıdır. Bu, həqiqətən CPU işidir - hətta mövcud hash-da uzun sorğu mətni tapmaq o qədər də asan deyil. Buna görə də, nəticə sadədir - sorğu yaratmayın. Onları bir dəyişəndə ​​saxlayın. Və sevin.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Növbəti problem. Məlumat növləri vacibdir. ORM-lər var ki, hansı növ NULL olmasının əhəmiyyəti yoxdur, qoy bir növ olsun. Əgər Int, onda setInt deyirik. Əgər NULL olarsa, o, həmişə VARCHAR olsun. Və sonda NULL-un nə fərqi var? Verilənlər bazası özü hər şeyi başa düşəcək. Və bu şəkil işləmir.

Praktikada verilənlər bazası heç bir əhəmiyyət kəsb etmir. Əgər siz birinci dəfə bunun bir nömrə olduğunu və ikinci dəfə bunun VARCHAR olduğunu söylədinizsə, Server tərəfindən hazırlanmış ifadələri təkrar istifadə etmək mümkün deyil. Və bu halda biz öz bəyanatımızı yenidən yaratmalıyıq.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Eyni sorğunu yerinə yetirirsinizsə, sütununuzdakı məlumat növlərinin qarışıq olmadığına əmin olun. NULL-ə diqqət yetirməlisiniz. Bu, PreparedStatements-dən istifadə etməyə başladıqdan sonra rastlaşdığımız ümumi səhvdir

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Tamam, yandırıldı. Bəlkə də sürücünü aparıblar. Və məhsuldarlıq aşağı düşdü. İşlər pisləşdi.

Bu necə baş verir? Bu səhv və ya xüsusiyyətdir? Təəssüf ki, bunun səhv və ya xüsusiyyət olduğunu anlamaq mümkün olmadı. Ancaq bu problemi təkrarlamaq üçün çox sadə bir ssenari var. O, tamamilə gözlənilmədən bizi pusquya saldı. Və hərfi mənada bir cədvəldən nümunə götürməkdən ibarətdir. Təbii ki, belə müraciətlərimiz daha çox olub. Bir qayda olaraq, iki və ya üç masa daxil etdilər, lakin belə bir oynatma ssenarisi var. Verilənlər bazanızdan istənilən versiyanı götürün və onu oynayın.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Məsələ burasındadır ki, hər biri indeksləşdirilmiş iki sütunumuz var. Bir NULL sütunda bir milyon sətir var. İkinci sütunda isə cəmi 20 sətir var. Bağlı dəyişənlər olmadan icra etdikdə hər şey yaxşı işləyir.

Bağlanmış dəyişənlərlə icra etməyə başlasaq, yəni "?" və ya sorğumuz üçün “$1”, biz nə əldə edirik?

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

İlk icra gözlənildiyi kimidir. İkincisi bir az daha sürətlidir. Nəsə keşlənib. Üçüncü, dördüncü, beşinci. Sonra bang - və buna bənzər bir şey. Ən pisi isə odur ki, bu, altıncı edamda baş verir. Kim bilirdi ki, faktiki icra planının nə olduğunu başa düşmək üçün düz altı edam etmək lazımdır?

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Kim günahkardır? Nə olub? Verilənlər bazasında optimallaşdırma var. Və ümumi hal üçün optimallaşdırıldığı görünür. Və müvafiq olaraq, bir nöqtədən başlayaraq, təəssüf ki, fərqli ola biləcək ümumi bir plana keçir. Eyni ola bilər, fərqli də ola bilər. Və bu davranışa səbəb olan bir növ hədd dəyəri var.

Bununla bağlı nə edə bilərsiniz? Burada, təbii ki, nəyisə güman etmək daha çətindir. İstifadə etdiyimiz sadə bir həll var. Bu +0, OFFSET 0. Şübhəsiz ki, belə həlləri bilirsiniz. Sadəcə götürürük və sorğuya “+0” əlavə edirik və hər şey qaydasındadır. Mən sizə sonra göstərəcəyəm.

Və başqa bir seçim var - planlara daha diqqətlə baxın. Tərtibatçı təkcə sorğu yazmamalı, həm də 6 dəfə “analizi izah et” deməlidir. Əgər 5 olarsa, işləməyəcək.

Üçüncü variant da var - pgsql-hackerlərə məktub yazın. Yazdım, lakin bunun bir səhv və ya bir xüsusiyyət olduğu hələ aydın deyil.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Bunun bir səhv və ya bir xüsusiyyət olduğunu düşünərkən, gəlin onu düzəldək. Gəlin sorğumuzu götürüb “+0” əlavə edək. Hər şey yaxşıdır. İki simvol və bunun necə və ya nə olduğunu düşünməyə belə ehtiyac yoxdur. Çox sadə. Biz sadəcə olaraq verilənlər bazasına bu sütunda indeksdən istifadə etməyi qadağan etdik. "+0" sütununda indeksimiz yoxdur və budur, verilənlər bazası indeksdən istifadə etmir, hər şey qaydasındadır.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bu 6-cı qaydanı izah edir. İndi cari versiyalarda bağlı dəyişənlər varsa, bunu 6 dəfə etməlisiniz. Bağlanmış dəyişənləriniz yoxdursa, biz bunu edirik. Və sonda uğursuz olan məhz bu tələbdir. Bu çətin bir şey deyil.

Görünür, nə qədər mümkündür? Burada bir səhv, orada bir səhv. Əslində, səhv hər yerdədir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Gəlin daha yaxından nəzər salaq. Məsələn, iki sxemimiz var. S cədvəli ilə A sxemi və S cədvəli ilə B diaqramı. Sorğu - cədvəldən məlumatları seçin. Bu vəziyyətdə nəyə sahib olacağıq? Bir səhvimiz olacaq. Yuxarıdakıların hamısına sahib olacağıq. Qayda budur - bir səhv hər yerdədir, yuxarıda göstərilənlərin hamısına sahib olacağıq.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

İndi sual: “Niyə?” Deyəsən, sənədləşmə var ki, əgər sxemimiz varsa, o zaman cədvəli harada axtaracağımızı bildirən "axtarış_yolu" dəyişəni var. Belə görünür ki, dəyişən var.

Problem nədir? Problem ondadır ki, server tərəfindən hazırlanmış bəyanatlar axtarış_yolunun kimsə tərəfindən dəyişdirilə biləcəyindən şübhələnmir. Bu dəyər verilənlər bazası üçün olduğu kimi sabit qalır. Və bəzi hissələr yeni mənalar qəbul etməyə bilər.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Əlbəttə ki, bu, sınaqdan keçirdiyiniz versiyadan asılıdır. Cədvəllərinizin nə qədər ciddi fərqləndiyindən asılıdır. 9.1 versiyası isə sadəcə olaraq köhnə sorğuları yerinə yetirəcək. Yeni versiyalar səhvi tuta bilər və sizə səhviniz olduğunu söyləyə bilər.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

search_path + server tərəfindən hazırlanmış ifadələri təyin edin =
keşlənmiş plan nəticə növünü dəyişməməlidir

Bunu necə müalicə etmək olar? Sadə bir resept var - bunu etməyin. Proqram işləyərkən search_path dəyişdirməyə ehtiyac yoxdur. Dəyişsəniz, yeni bir əlaqə yaratmaq daha yaxşıdır.

Siz müzakirə edə bilərsiniz, yəni açmaq, müzakirə etmək, əlavə etmək. Bəlkə verilənlər bazası tərtibatçılarını inandıra bilərik ki, kimsə dəyəri dəyişdikdə verilənlər bazası bu barədə müştəriyə məlumat verməlidir: “Bax, burada sizin dəyəriniz yenilənib. Bəlkə ifadələri yenidən qurmaq və onları yenidən yaratmaq lazımdır?” İndi verilənlər bazası gizli şəkildə davranır və ifadələrin içəridə bir yerdə dəyişdiyini heç bir şəkildə bildirmir.

Və yenə də vurğulayacağam - bu Java üçün xarakterik olmayan bir şeydir. Eyni şeyi PL/pgSQL-də bir-bir görəcəyik. Amma orada təkrarlanacaq.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Gəlin daha çox məlumat seçiminə cəhd edək. Biz seçirik və seçirik. Bir milyon sıradan ibarət bir cədvəlimiz var. Hər sətir bir kilobaytdır. Təxminən bir gigabayt məlumat. Və bizim Java maşınında 128 meqabaytlıq işləyən yaddaşımız var.

Biz, bütün kitablarda tövsiyə olunduğu kimi, axın emalından istifadə edirik. Yəni biz resultSet-i açıb oradan yavaş-yavaş məlumatları oxuyuruq. Bu işləyəcək? Yaddaşdan düşəcəkmi? Bir az oxuyarsan? Gəlin verilənlər bazasına, Postgresə etibar edək. Biz buna inanmırıq. OutOFMemory düşəcəyik? OutOfMemory ilə kim təcrübə keçirdi? Bundan sonra kim düzəldə bildi? Kimsə bunu düzəltməyə müvəffəq oldu.

Bir milyon sıranız varsa, sadəcə seçib seçə bilməzsiniz. OFFSET/LIMIT tələb olunur. Bu seçim üçün kimdir? Bəs kim autoCommit ilə oynamağın tərəfdarıdır?

Burada, həmişəki kimi, ən gözlənilməz variant doğru çıxır. Və birdən autoCommit-i söndürsəniz, bu kömək edəcəkdir. Niyə belədir? Elmin bundan xəbəri yoxdur.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Ancaq standart olaraq, Postgres verilənlər bazasına qoşulan bütün müştərilər bütün məlumatları alır. PgJDBC bu baxımdan istisna deyil, bütün sətirləri seçir.

FetchSize mövzusunda bir dəyişiklik var, yəni ayrıca bəyanat səviyyəsində deyə bilərsiniz ki, burada məlumatı 10, 50-yə seçin. AutoCommit söndürüldü - işə başlayır.

Lakin koddan keçmək və setFetchSize-i hər yerdə quraşdırmaq əlverişsizdir. Buna görə də, bütün əlaqə üçün standart dəyəri söyləyəcək bir parametr etdik.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Biz bunu dedik. Parametr konfiqurasiya edilib. Və nə əldə etdik? Kiçik məbləğləri seçsək, məsələn, bir anda 10 cərgə seçsək, o zaman çox böyük qaimə xərclərimiz olur. Buna görə də, bu dəyər təxminən yüz təyin edilməlidir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

İdeal olaraq, əlbəttə ki, siz hələ də baytlarla məhdudlaşdırmağı öyrənməlisiniz, lakin resept belədir: defaultRowFetchSize-i yüzdən çox təyin edin və xoşbəxt olun.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Gəlin məlumatların daxil edilməsinə keçək. Daxil etmək daha asandır, müxtəlif variantlar var. Məsələn, INSERT, VALUES. Bu yaxşı seçimdir. Siz “SERT SEÇİN” deyə bilərsiniz. Praktikada eyni şeydir. Performans baxımından heç bir fərq yoxdur.

Kitablar Batch ifadəsini yerinə yetirməli olduğunuzu söyləyir, kitablar bir neçə mötərizə ilə daha mürəkkəb əmrləri yerinə yetirə biləcəyinizi söyləyir. Postgresin gözəl bir xüsusiyyəti var - siz KOPYA edə bilərsiniz, yəni bunu daha sürətli edə bilərsiniz.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bunu ölçsəniz, yenə maraqlı kəşflər edə bilərsiniz. Bunun necə işləməsini istəyirik? Biz təhlil etməmək və lazımsız əmrləri yerinə yetirməmək istəyirik.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Praktikada TCP bizə bunu etməyə imkan vermir. Müştəri sorğu göndərməklə məşğuldursa, verilənlər bazası bizə cavab göndərmək cəhdlərində sorğuları oxumur. Son nəticə odur ki, müştəri verilənlər bazasının sorğunu oxumasını, verilənlər bazası isə müştərinin cavabı oxumasını gözləyir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Və buna görə də müştəri vaxtaşırı sinxronizasiya paketi göndərməyə məcbur olur. Əlavə şəbəkə qarşılıqlı əlaqəsi, əlavə vaxt itkisi.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir SitnikovVə onları nə qədər çox əlavə etsək, bir o qədər pis olur. Sürücü kifayət qədər bədbindir və onları tez-tez əlavə edir, xətlərin ölçüsündən asılı olaraq təxminən 200 sətirdə bir dəfə və s.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/380

Elə olur ki, sadəcə bir sətri düzəldin və hər şey 10 dəfə sürətlənəcək. Baş verir. Niyə? Həmişə olduğu kimi, belə bir sabit artıq bir yerdə istifadə edilmişdir. Və “128” dəyəri yığımdan istifadə etməməyi nəzərdə tuturdu.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Java mikrobenchmark qoşqu

Bunun rəsmi versiyaya daxil edilməməsi yaxşıdır. Buraxılış başlamazdan əvvəl kəşf edildi. Verdiyim mənaların hamısı müasir versiyalara əsaslanır.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Gəlin onu sınayaq. Biz sadə InsertBatch-i ölçürük. InsertBatch-i bir neçə dəfə ölçürük, yəni eyni şeyi, lakin çoxlu dəyərlər var. Çətin hərəkət. Hər kəs bunu edə bilməz, lakin bu, KOPYALAMA-dan çox sadə bir hərəkətdir.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

KOPYA edə bilərsiniz.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Və bunu strukturlarda edə bilərsiniz. İstifadəçinin defolt tipini elan edin, massivi keçin və birbaşa cədvələ INSERT edin.

Əgər linki açsanız: pgjdbc/ubenchmsrk/InsertBatch.java, onda bu kod GitHub-dadır. Orada xüsusi olaraq hansı sorğuların yaradıldığını görə bilərsiniz. Fərqi yoxdur.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Biz işə saldıq. Və başa düşdüyümüz ilk şey o oldu ki, partiyadan istifadə etməmək sadəcə mümkün deyil. Bütün toplu seçim variantları sıfırdır, yəni birdəfəlik icra ilə müqayisədə icra müddəti praktiki olaraq sıfırdır.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Biz məlumatları daxil edirik. Çox sadə masadır. Üç sütun. Və biz burada nə görürük? Biz görürük ki, bu üç variantın hamısı təxminən müqayisə oluna bilər. Və KOPYA, əlbəttə ki, daha yaxşıdır.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Parçaları daxil etdiyimiz zaman budur. Bir VALUES dəyəri, iki VALUES dəyəri, üç DƏYƏRLƏR dəyəri dedikdə və ya onlardan 10-nu vergüllə ayırdıq. Bu, indi sadəcə üfüqidir. 1, 2, 4, 128. Görünür ki, mavi rənglə çəkilmiş Batch Insert onu çox yaxşı hiss edir. Yəni, bir-bir daxil etdikdə və ya hər dəfə dörd əlavə etdikdə, DƏYƏRLƏRə bir az daha sıxışdırdığımız üçün ikiqat yaxşı olur. Daha az EXECUTE əməliyyatları.

COPY-nin kiçik həcmlərdə istifadəsi son dərəcə perspektivsizdir. İlk ikisini heç çəkmədim. Cənnətə gedirlər, yəni KOPYA üçün bu yaşıl nömrələr.

Ən azı yüz sətir məlumatınız olduqda COPY istifadə edilməlidir. Bu əlaqənin açılmasının yükü böyükdür. Düzünü desəm, bu istiqamətdə qazmadım. Mən Batch-i optimallaşdırdım, lakin KOPYALAMA.

Bundan sonra nə edəcəyik? Biz sınadıq. Biz başa düşürük ki, ya strukturlardan, ya da bir neçə mənası birləşdirən ağıllı bir bacdan istifadə etmək lazımdır.

PostgreSQL və JDBC bütün suyu sıxır. Vladimir Sitnikov

Bugünkü hesabatdan nəyi götürməlisiniz?

  • PreparedStatement bizim hər şeyimizdir. Bu, məhsuldarlığa çox şey verir. O, məlhəmdə böyük bir flop yaradır.
  • Və 6 dəfə İZAHI ANALİZ etməlisən.
  • Problemli sorğularımızın qalan faizini düzəltmək üçün OFFSET 0 və +0 kimi fəndləri sulandırmaq lazımdır.

Mənbə: www.habr.com

Добавить комментарий