PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Առաջարկում եմ կարդալ Վլադիմիր Սիտնիկովի 2016 թվականի սկզբի զեկույցի սղագրությունը «PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը»

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Բարի օր Ես Վլադիմիր Սիտնիկովն եմ։ Ես աշխատում եմ NetCracker-ում արդեն 10 տարի: Եվ ես հիմնականում զբաղվում եմ արտադրողականությամբ: Java-ի հետ կապված ամեն ինչ, SQL-ի հետ կապված ամեն ինչ այն է, ինչ ես սիրում եմ:

Իսկ այսօր ես կխոսեմ այն ​​մասին, թե ինչի հետ հանդիպեցինք ընկերությունում, երբ սկսեցինք օգտագործել PostgreSQL-ը որպես տվյալների բազայի սերվեր։ Իսկ մենք հիմնականում աշխատում ենք Java-ի հետ։ Բայց այն, ինչ ես ձեզ այսօր կպատմեմ, միայն Java-ի մասին չէ: Ինչպես ցույց է տվել պրակտիկան, դա տեղի է ունենում նաև այլ լեզուներով:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Մենք կխոսենք.

  • տվյալների նմուշառման մասին։
  • Տվյալների պահպանման մասին.
  • Եվ նաև կատարման մասին:
  • Իսկ այնտեղ թաղված ստորջրյա փոցխերի մասին։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Սկսենք մի պարզ հարցից. Աղյուսակից ընտրում ենք մեկ տող՝ հիմնվելով հիմնական բանալի վրա։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Տվյալների բազան գտնվում է նույն հոսթի վրա: Եվ այս ամբողջ գյուղատնտեսությունը տևում է 20 միլիվայրկյան:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Այս 20 միլիվայրկյանները շատ են: Եթե ​​դուք ունեք 100 նման հարցումներ, ապա դուք վայրկյանում ժամանակ եք ծախսում այս հարցումները պտտելու համար, այսինքն՝ մենք ժամանակ ենք կորցնում:

Մենք չենք սիրում դա անել և տեսնենք, թե ինչ է մեզ առաջարկում բազան դրա համար: Տվյալների բազան մեզ առաջարկում է հարցումներ կատարելու երկու տարբերակ.

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Առաջին տարբերակը պարզ խնդրանքն է: Ի՞նչ լավ բան կա դրա մեջ: Այն, որ վերցնում ենք ու ուղարկում, և ոչ ավելին։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Տվյալների բազան ունի նաև առաջադեմ հարցում, որն ավելի բարդ է, բայց ավելի ֆունկցիոնալ: Դուք կարող եք առանձին ուղարկել վերլուծության, կատարման, փոփոխական կապման հարցում և այլն:

Գեր ընդլայնված հարցումը մի բան է, որը մենք չենք անդրադառնա ընթացիկ զեկույցում: Մենք, երևի, ինչ-որ բան ենք ուզում տվյալների բազայից, և կա ցանկությունների ցուցակ, որը ձևավորվել է ինչ-որ ձևով, այսինքն՝ սա այն է, ինչ մենք ուզում ենք, բայց հիմա և հաջորդ տարի դա անհնար է։ Այսպիսով, մենք պարզապես ձայնագրեցինք այն և կշրջենք՝ ցնցելով հիմնական մարդկանց:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եվ այն, ինչ մենք կարող ենք անել, պարզ հարցումն է և ընդլայնված հարցումը:

Ինչն է առանձնահատուկ յուրաքանչյուր մոտեցման մեջ:

Պարզ հարցումը լավ է մեկանգամյա կատարման համար: Մի անգամ արված և մոռացված: Եվ խնդիրն այն է, որ այն չի աջակցում երկուական տվյալների ձևաչափին, այսինքն՝ այն հարմար չէ բարձր արդյունավետության որոշ համակարգերի համար:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Ընդլայնված հարցում – թույլ է տալիս ժամանակ խնայել վերլուծության վրա: Սա այն է, ինչ մենք արեցինք և սկսեցինք օգտագործել: Սա իսկապես, իսկապես օգնեց մեզ: Խնայողություններ կան ոչ միայն վերլուծության վրա: Տվյալների փոխանցման խնայողություններ կան: Երկուական ձևաչափով տվյալների փոխանցումը շատ ավելի արդյունավետ է:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Անցնենք պրակտիկային։ Ահա թե ինչ տեսք ունի տիպիկ հավելվածը։ Դա կարող է լինել Java և այլն:

Մենք ստեղծել ենք հայտարարություն. Կատարեց հրամանը. Ստեղծվել է մոտ. Որտեղ է այստեղ սխալը: Ինչումն է խնդիրը? Ոչ մի խնդիր. Ահա թե ինչ է ասվում բոլոր գրքերում. Այսպես պետք է գրել. Եթե ​​ցանկանում եք առավելագույն կատարողականություն, գրեք այսպես.

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Բայց պրակտիկան ցույց է տվել, որ դա չի աշխատում: Ինչո՞ւ։ Քանի որ մենք ունենք «փակ» մեթոդ. Եվ երբ մենք դա անում ենք, տվյալների բազայի տեսանկյունից պարզվում է, որ դա նման է ծխողի, որն աշխատում է տվյալների բազայի հետ: Մենք ասացինք «PARSE EXECUTE DEALLOCATE»:

Ինչու՞ հայտարարությունների այս ավելորդ ստեղծումն ու բեռնաթափումը։ Դրանք ոչ մեկին պետք չեն։ Բայց այն, ինչ սովորաբար տեղի է ունենում PreparedStatements-ում, այն է, որ երբ մենք դրանք փակում ենք, նրանք փակում են տվյալների բազայի ամեն ինչ: Սա այն չէ, ինչ մենք ուզում ենք։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Մենք ցանկանում ենք, ինչպես առողջ մարդիկ, աշխատել բազայի հետ։ Մեկ անգամ վերցրել ու պատրաստել ենք մեր հայտարարությունը, հետո բազմիցս կատարում ենք։ Իրականում, շատ անգամ, սա մեկ անգամ է դիմումների ողջ կյանքում, դրանք վերլուծվել են: Եվ մենք օգտագործում ենք նույն հայտարարության id-ը տարբեր REST-ների վրա: Սա է մեր նպատակը։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Ինչպե՞ս կարող ենք դրան հասնել:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Դա շատ պարզ է՝ հայտարարությունները փակելու կարիք չկա: Մենք գրում ենք այսպես՝ «պատրաստել» «կատարել»։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եթե ​​մենք գործարկենք նման բան, ապա պարզ է, որ ինչ-որ բան ինչ-որ տեղ կհեղեղի: Եթե ​​պարզ չէ, կարող եք փորձել: Եկեք գրենք չափանիշ, որն օգտագործում է այս պարզ մեթոդը: Ստեղծեք հայտարարություն. Մենք այն գործարկում ենք վարորդի ինչ-որ տարբերակի վրա և պարզում ենք, որ այն բավականին արագ խափանում է՝ կորցնելով ամբողջ հիշողությունը, որն ուներ:

Հասկանալի է, որ նման սխալները հեշտությամբ ուղղվում են։ Ես նրանց մասին չեմ խոսի։ Բայց ասեմ, որ նոր տարբերակը շատ ավելի արագ է աշխատում։ Մեթոդը հիմար է, բայց դեռ.

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Ինչպե՞ս ճիշտ աշխատել: Ի՞նչ պետք է անենք դրա համար:

Իրականում դիմումները միշտ փակում են հայտարարությունները: Բոլոր գրքերում ասում են՝ փակիր, թե չէ հիշողությունը կթողնի։

Իսկ PostgreSQL-ը չգիտի՝ ինչպես քեշավորել հարցումները: Անհրաժեշտ է, որ յուրաքանչյուր նիստ իր համար ստեղծի այս քեշը:

Եվ մենք նույնպես չենք ուզում ժամանակ վատնել վերլուծության վրա:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եվ ինչպես միշտ, մենք ունենք երկու տարբերակ.

Առաջին տարբերակն այն է, որ մենք վերցնում ենք այն և ասում, որ եկեք ամեն ինչ փաթաթենք PgSQL-ով: Այնտեղ կա քեշ։ Այն պահում է ամեն ինչ: Հիանալի կստացվի։ Մենք սա տեսանք։ Մենք ունենք 100500 հարցում։ Չի աշխատում. Մենք համաձայն չենք հարցումները ձեռքով ընթացակարգի վերածել: Ոչ ոչ.

Մենք ունենք երկրորդ տարբերակ՝ վերցրեք և ինքներս կտրեք։ Մենք բացում ենք աղբյուրները և սկսում կտրատել։ Տեսանք ու տեսանք։ Պարզվեց, որ դա այնքան էլ դժվար չէ անել։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Սա հայտնվեց 2015 թվականի օգոստոսին։ Այժմ կա ավելի ժամանակակից տարբերակ։ Եվ ամեն ինչ հիանալի է: Այն այնքան լավ է աշխատում, որ մենք ոչինչ չենք փոխում հավելվածում։ Եվ մենք նույնիսկ դադարեցինք մտածել PgSQL-ի ուղղությամբ, այսինքն՝ սա բավական էր, որպեսզի բոլոր վերադիր ծախսերը գրեթե զրոյի հասցնենք:

Համապատասխանաբար, սերվերի կողմից պատրաստված հայտարարություններն ակտիվանում են 5-րդ կատարման ժամանակ, որպեսզի խուսափեն տվյալների բազայում հիշողությունը վատնելուց յուրաքանչյուր մեկանգամյա հարցումով:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Կարող եք հարցնել՝ որտե՞ղ են թվերը: Ի՞նչ եք ստանում: Եվ այստեղ ես թվեր չեմ տա, քանի որ յուրաքանչյուր խնդրանք ունի իր սեփականը:

Մեր հարցումներն այնպիսին էին, որ մենք ծախսեցինք մոտ 20 միլիվայրկյան OLTP հարցումների վերլուծության վրա: Կատարման համար կար 0,5 միլիվայրկյան, վերլուծության համար՝ 20 միլիվայրկյան: Հարցում – 10 ԿԲ տեքստ, 170 տող պլան: Սա OLTP հարցում է: Այն պահանջում է 1, 5, 10 տող, երբեմն ավելի շատ:

Բայց մենք ընդհանրապես չէինք ուզում վատնել 20 միլիվայրկյան: Մենք այն իջեցրինք 0-ի։ Ամեն ինչ հիանալի է:

Ի՞նչ կարող ես վերցնել այստեղից: Եթե ​​ունես Java, ուրեմն վերցնում ես դրայվերի ժամանակակից տարբերակը ու ուրախանում։

Եթե ​​դուք խոսում եք այլ լեզվով, ապա մտածեք. գուցե սա ձեզ էլ է պետք: Որովհետև վերջնական լեզվի տեսանկյունից, օրինակ, եթե PL 8 կամ դուք ունեք LibPQ, ապա ձեզ համար ակնհայտ չէ, որ դուք ժամանակ եք ծախսում ոչ թե կատարման, վերլուծության վրա, և դա արժե ստուգել: Ինչպե՞ս: Ամեն ինչ անվճար է։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Միայն թե կան սխալներ և որոշ առանձնահատկություններ։ Եվ մենք նրանց մասին կխոսենք հենց հիմա: Դրա մեծ մասը կլինի արդյունաբերական հնագիտության մասին, այն մասին, թե ինչ գտանք, ինչի հանդիպեցինք:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եթե ​​հարցումը ստեղծվում է դինամիկ: Պատահում է. Ինչ-որ մեկը սոսնձում է տողերը, արդյունքում ստացվում է SQL հարցում:

Ինչու է նա վատը: Դա վատ է, քանի որ ամեն անգամ մենք հայտնվում ենք տարբեր լարերի հետ:

Եվ այս տարբեր տողի hashCode-ը պետք է նորից կարդալ: Սա իսկապես պրոցեսորի խնդիր է. երկար հարցման տեքստ գտնելն անգամ գոյություն ունեցող հեշում այնքան էլ հեշտ չէ: Հետևաբար, եզրակացությունը պարզ է՝ հարցումներ չառաջացնել: Պահպանեք դրանք մեկ փոփոխականի մեջ: Եվ ուրախացեք:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Հաջորդ խնդիրը. Տվյալների տեսակները կարևոր են: Կան ORM-ներ, որոնք ասում են, որ կարևոր չէ, թե ինչ տեսակի NULL կա, թող լինի մի տեսակ: Եթե ​​Int, ապա մենք ասում ենք setInt: Իսկ եթե NULL, ապա թող միշտ լինի VARCHAR: Եվ ի՞նչ տարբերություն, ի վերջո, թե ինչ NULL կա: Տվյալների բազան ինքնին կհասկանա ամեն ինչ։ Եվ այս նկարը չի աշխատում:

Գործնականում տվյալների բազան ընդհանրապես չի հետաքրքրում: Եթե ​​առաջին անգամ ասացիք, որ սա թիվ է, իսկ երկրորդ անգամ ասացիք, որ դա VARCHAR է, ապա անհնար է կրկին օգտագործել Սերվերի կողմից պատրաստված հայտարարությունները։ Եվ այս դեպքում մենք պետք է վերստեղծենք մեր հայտարարությունը։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եթե ​​դուք կատարում եք նույն հարցումը, համոզվեք, որ ձեր սյունակի տվյալների տեսակները շփոթված չեն: Դուք պետք է ուշադիր լինեք NULL-ի համար: Սա սովորական սխալ է, որը մենք ունեցել ենք PreparedStatements-ի օգտագործումից հետո

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Լավ, միացված է: Երևի վարորդին են տարել։ Եվ արտադրողականությունը նվազել է: Գործերը վատացան:

Ինչպե՞ս է դա տեղի ունենում: Սա վրիպակ է, թե՞ հատկանիշ: Ցավոք, չհաջողվեց հասկանալ՝ սա վրիպակ է, թե հատկանիշ։ Բայց այս խնդիրը վերարտադրելու շատ պարզ սցենար կա. Նա բոլորովին անսպասելիորեն դարանակալեց մեզ։ Եվ այն բաղկացած է բառացիորեն մեկ աղյուսակից նմուշառումից։ Մենք, իհարկե, ավելի շատ նման խնդրանքներ ունեինք։ Որպես կանոն, նրանք ներառում էին երկու կամ երեք աղյուսակ, բայց կա նման նվագարկման սցենար: Վերցրեք ցանկացած տարբերակ ձեր տվյալների բազայից և խաղացեք այն:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Բանն այն է, որ մենք ունենք երկու սյունակ, որոնցից յուրաքանչյուրը ինդեքսավորված է։ Մեկ NULL սյունակում կա միլիոն տող: Իսկ երկրորդ սյունակը պարունակում է ընդամենը 20 տող։ Երբ մենք կատարում ենք առանց կապված փոփոխականների, ամեն ինչ լավ է աշխատում:

Եթե ​​մենք սկսենք կատարել կապված փոփոխականներով, այսինքն՝ մենք կատարում ենք «?" կամ «$1» մեր խնդրանքի համար, ի՞նչ ենք մենք ստանում:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Առաջին մահապատիժը սպասվածի պես է. Երկրորդը մի փոքր ավելի արագ է։ Ինչ-որ բան պահվել է քեշում: Երրորդ, չորրորդ, հինգերորդ: Հետո պայթյուն - և նման մի բան: Իսկ ամենավատն այն է, որ դա տեղի է ունենում վեցերորդ մահապատժի ժամանակ։ Ո՞վ գիտեր, որ պետք է կատարել ուղիղ վեց մահապատիժ՝ հասկանալու համար, թե որն է իրականում կատարման ծրագիրը։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Ո՞վ է մեղավոր. Ինչ է պատահել? Տվյալների բազան պարունակում է օպտիմալացում: Եվ կարծես օպտիմիզացված է ընդհանուր գործի համար: Եվ, համապատասխանաբար, ինչ-որ պահից սկսած՝ նա անցնում է ընդհանուր պլանի, որը, ցավոք, կարող է տարբեր լինել։ Կարող է պարզվել, որ նույնն է, կամ կարող է տարբեր լինել: Եվ կա որոշակի շեմային արժեք, որը հանգեցնում է այս վարքագծին:

Ի՞նչ կարող ես անել դրա դեմ: Այստեղ, իհարկե, ավելի դժվար է ինչ-որ բան ենթադրել։ Կա մի պարզ լուծում, որը մենք օգտագործում ենք. Սա +0 է, OFFSET 0: Անշուշտ, դուք գիտեք նման լուծումներ: Մենք պարզապես վերցնում ենք այն և ավելացնում «+0» հարցումին, և ամեն ինչ լավ է: Ես ձեզ ավելի ուշ ցույց կտամ:

Եվ կա ևս մեկ տարբերակ՝ ավելի ուշադիր նայեք պլաններին։ Մշակողը պետք է ոչ միայն հարցում գրի, այլև 6 անգամ ասի «բացատրել վերլուծել»։ Եթե ​​5 լինի, չի աշխատի:

Եվ կա երրորդ տարբերակ՝ նամակ գրել pgsql-hackers-ին։ Գրեցի, սակայն, դեռ պարզ չէ՝ սա վրիպակ է, թե ֆունկցիա։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Մինչ մենք մտածում ենք՝ սա վրիպակ է, թե ֆունկցիա, եկեք շտկենք այն: Եկեք ընդունենք մեր խնդրանքը և ավելացնենք «+0»: Ամեն ինչ լավ է. Երկու խորհրդանիշ, և դուք նույնիսկ պետք չէ մտածել, թե ինչպես է այն կամ ինչ է դա: Շատ պարզ. Մենք պարզապես արգելեցինք տվյալների բազան օգտագործել ինդեքս այս սյունակում: Մենք չունենք ինդեքս «+0» սյունակում և վերջ, տվյալների բազան չի օգտագործում ինդեքսը, ամեն ինչ լավ է:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Սա 6 բացատրության կանոնն է: Այժմ ընթացիկ տարբերակներում դուք պետք է դա անեք 6 անգամ, եթե ունեք կապված փոփոխականներ: Եթե ​​դուք չունեք կապված փոփոխականներ, սա այն է, ինչ մենք անում ենք: Եվ վերջում հենց այս խնդրանքն է ձախողվում։ Դա բարդ բան չէ:

Թվում է, թե որքան հնարավոր է: Սխալ՝ այստեղ, վրիպակ՝ այնտեղ։ Իրականում, սխալն ամենուր է:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եկեք ավելի սերտ նայենք: Օրինակ, մենք ունենք երկու սխեմա. A սխեման S աղյուսակով և B դիագրամ S աղյուսակով: Հարցում – ընտրեք տվյալները աղյուսակից: Ի՞նչ կունենանք այս դեպքում։ Սխալ կունենանք. Մենք կունենանք վերը նշված բոլորը: Կանոնն է՝ ամենուր վրիպակ կա, մենք կունենանք վերը նշված բոլորը:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Այժմ հարցն այն է. «Ինչո՞ւ»: Թվում է, թե կա փաստաթուղթ, որ եթե մենք ունենք սխեմա, ապա կա «search_path» փոփոխական, որը մեզ ասում է, թե որտեղ փնտրել աղյուսակը: Թվում է, թե փոփոխական կա.

Ինչումն է խնդիրը? Խնդիրն այն է, որ սերվերի կողմից պատրաստված հայտարարությունները չեն կասկածում, որ search_path-ը կարող է փոխվել ինչ-որ մեկի կողմից: Այս արժեքը, կարծես, մնում է անփոփոխ տվյալների բազայի համար: Եվ որոշ մասեր կարող են նոր իմաստներ չստանալ:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Իհարկե, դա կախված է այն տարբերակից, որը դուք փորձարկում եք: Կախված է նրանից, թե որքանով են տարբերվում ձեր սեղանները: Իսկ 9.1 տարբերակը պարզապես կկատարի հին հարցումները: Նոր տարբերակները կարող են բռնել վրիպակը և ասել, որ դուք սխալ ունեք:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Սահմանել search_path + սերվերի կողմից պատրաստված հայտարարություններ =
քեշավորված պլանը չպետք է փոխի արդյունքի տեսակը

Ինչպե՞ս բուժել այն: Կա մի պարզ բաղադրատոմս՝ մի արեք դա։ Երբ հավելվածն աշխատում է, կարիք չկա փոխել search_path-ը: Եթե ​​փոխեք, ավելի լավ է նոր կապ ստեղծել։

Դուք կարող եք քննարկել, այսինքն բացել, քննարկել, ավելացնել: Միգուցե մենք կարողանանք համոզել տվյալների բազայի մշակողներին, որ երբ ինչ-որ մեկը փոխում է արժեքը, տվյալների բազան պետք է հաճախորդին ասի այս մասին. «Տեսեք, ձեր արժեքը թարմացվել է այստեղ: Միգուցե պետք է զրոյացնել հայտարարությունները և վերստեղծե՞լ դրանք»։ Հիմա տվյալների բազան իրեն գաղտնի է պահում և ոչ մի կերպ չի հայտնում, որ ներսում ինչ-որ տեղ փոխվել են հայտարարությունները։

Եվ նորից շեշտեմ՝ սա Java-ին բնորոշ մի բան է։ Մենք նույն բանը կտեսնենք PL/pgSQL-ում մեկ առ մեկ: Բայց այնտեղ կվերարտադրվի։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Փորձենք ավելի շատ տվյալների ընտրություն: Մենք ընտրում ենք և ընտրում։ Մենք ունենք մեկ միլիոն տող ունեցող աղյուսակ: Յուրաքանչյուր տող մեկ կիլոբայթ է: Մոտավորապես մեկ գիգաբայթ տվյալներ: Իսկ Java մեքենայում մենք ունենք 128 մեգաբայթանոց աշխատանքային հիշողություն։

Մենք, ինչպես խորհուրդ է տրվում բոլոր գրքերում, օգտագործում ենք հոսքային մշակում: Այսինքն՝ բացում ենք resultSet-ը ու այնտեղից կամաց-կամաց կարդում ենք տվյալները։ Արդյո՞ք դա կաշխատի: Կընկնի հիշողությունից? Մի քիչ կկարդա՞ք։ Եկեք վստահենք տվյալների բազային, եկեք վստահենք Postgres-ին: Մենք դրան չենք հավատում: Մենք դուրս կգա՞նք հիշողությունից: Ո՞վ է զգացել OutOfMemory-ը: Ո՞վ կարողացավ դրանից հետո շտկել։ Ինչ-որ մեկին հաջողվեց շտկել:

Եթե ​​դուք ունեք մեկ միլիոն տող, դուք չեք կարող պարզապես ընտրել և ընտրել: Պահանջվում է OFFSET/LIMIT: Ո՞վ է կողմ այս տարբերակին: Իսկ ո՞վ է կողմ autoCommit-ով խաղալուն։

Այստեղ, ինչպես միշտ, ամենաանսպասելի տարբերակը ճիշտ է ստացվում։ Իսկ եթե հանկարծ անջատեք autoCommit-ը, դա կօգնի։ Ինչո՞ւ է այդպես։ Գիտությունը չգիտի այս մասին։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Բայց լռելյայնորեն, բոլոր հաճախորդները, որոնք միանում են Postgres տվյալների բազային, վերցնում են ամբողջ տվյալները: PgJDBC-ն այս առումով բացառություն չէ, այն ընտրում է բոլոր տողերը:

Կա FetchSize թեմայի փոփոխություն, այսինքն՝ դուք կարող եք առանձին հայտարարության մակարդակով ասել, որ այստեղ խնդրում ենք ընտրել տվյալները 10, 50-ով: Բայց սա չի աշխատում, քանի դեռ չեք անջատել autoCommit-ը: Անջատված է autoCommit - այն սկսում է աշխատել:

Բայց կոդի միջով անցնելը և ամենուր setFetchSize սահմանելը անհարմար է: Հետևաբար, մենք կատարել ենք կարգավորում, որը կասի լռելյայն արժեքը ամբողջ կապի համար:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Այդպես էլ ասացինք։ Պարամետրը կարգավորվել է: Իսկ ի՞նչ ստացանք։ Եթե ​​մենք ընտրում ենք փոքր գումարներ, եթե, օրինակ, ընտրում ենք 10 տող միաժամանակ, ապա ունենք շատ մեծ վերադիր ծախսեր։ Հետեւաբար, այս արժեքը պետք է սահմանվի մոտ հարյուր:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Իդեալում, իհարկե, դուք դեռ պետք է սովորեք, թե ինչպես սահմանափակել այն բայթերով, բայց բաղադրատոմսը հետևյալն է. defaultRowFetchSize սահմանեք հարյուրից ավելի և երջանիկ եղեք:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Անցնենք տվյալների տեղադրմանը։ Տեղադրումն ավելի հեշտ է, կան տարբեր տարբերակներ: Օրինակ՝ INSERT, VALUES: Սա լավ տարբերակ է։ Դուք կարող եք ասել «INSERT SELECT»: Գործնականում նույն բանն է. Կատարման մեջ տարբերություն չկա։

Գրքերն ասում են, որ դուք պետք է կատարեք Batch հայտարարություն, գրքերում ասվում է, որ դուք կարող եք ավելի բարդ հրամաններ կատարել մի քանի փակագծերով: Իսկ Postgres-ն ունի մի հրաշալի հատկություն՝ դուք կարող եք COPY անել, այսինքն՝ ավելի արագ:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եթե ​​չափեք այն, կարող եք կրկին մի քանի հետաքրքիր բացահայտումներ անել: Ինչպե՞ս ենք մենք ուզում, որ սա աշխատի: Մենք ցանկանում ենք չվերլուծել և չկատարել ավելորդ հրամանները:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Գործնականում TCP-ն մեզ թույլ չի տալիս դա անել: Եթե ​​հաճախորդը զբաղված է հարցում ուղարկելով, ապա տվյալների բազան չի կարդում հարցումները՝ փորձելով մեզ պատասխաններ ուղարկել: Վերջնական արդյունքն այն է, որ հաճախորդը սպասում է, որ տվյալների բազան կարդա հարցումը, իսկ տվյալների բազան սպասում է, որ հաճախորդը կարդա պատասխանը:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եվ հետևաբար հաճախորդը ստիպված է լինում պարբերաբար ուղարկել համաժամացման փաթեթ: Լրացուցիչ ցանցային փոխազդեցություններ, լրացուցիչ ժամանակի վատնում:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր ՍիտնիկովԵվ որքան շատ ենք դրանք ավելացնում, այնքան վատանում է: Վարորդը բավականին հոռետես է և դրանք ավելացնում է բավականին հաճախ՝ մոտավորապես 200 տողում մեկ անգամ՝ կախված գծերի չափից և այլն։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

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

Պատահում է, որ դուք ուղղում եք ընդամենը մեկ տող, և ամեն ինչ կարագանա 10 անգամ։ Պատահում է. Ինչո՞ւ։ Ինչպես միշտ, նման հաստատուն ինչ-որ տեղ արդեն օգտագործվել է։ Իսկ «128» արժեքը նշանակում էր չօգտագործել խմբաքանակ:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Java microbenchmark զրահ

Լավ է, որ սա չի ներառվել պաշտոնական տարբերակում։ Հայտնաբերվել է մինչև թողարկման սկսվելը: Իմ տված բոլոր իմաստները հիմնված են ժամանակակից տարբերակների վրա։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եկեք փորձենք այն: Մենք չափում ենք InsertBatch-ը պարզ: Մենք չափում ենք InsertBatch-ը մի քանի անգամ, այսինքն՝ նույն բանը, բայց շատ արժեքներ կան: Բարդ քայլ. Ոչ բոլորը կարող են դա անել, բայց դա այնքան պարզ քայլ է, որը շատ ավելի հեշտ է, քան COPY-ը:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Դուք կարող եք կատարել COPY:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Եվ դուք կարող եք դա անել կառույցների վրա: Հայտարարել Օգտատիրոջ լռելյայն տեսակը, փոխանցել զանգվածը և INSERT ուղղակիորեն աղյուսակում:

Եթե ​​բացեք հղումը՝ pgjdbc/ubenchmsrk/InsertBatch.java, ապա այս կոդը գտնվում է GitHub-ում: Դուք կարող եք տեսնել, թե կոնկրետ ինչ հարցումներ են ստեղծվում այնտեղ: Կարեւոր չէ։

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Մենք մեկնարկեցինք. Եվ առաջին բանը, որ մենք հասկացանք, այն էր, որ խմբաքանակ չօգտագործելը պարզապես անհնար է: Փաթեթավորման բոլոր տարբերակները զրո են, այսինքն՝ կատարման ժամանակը գործնականում զրոյական է մեկանգամյա կատարման համեմատ:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Մենք տեղադրում ենք տվյալներ. Շատ պարզ սեղան է։ Երեք սյունակ. Իսկ ի՞նչ ենք մենք տեսնում այստեղ։ Մենք տեսնում ենք, որ այս երեք տարբերակներն էլ մոտավորապես համեմատելի են: Իսկ COPY-ն, իհարկե, ավելի լավն է:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Սա այն դեպքում, երբ մենք տեղադրում ենք կտորներ: Երբ ասում էինք, որ մեկ VALUES արժեք, երկու VALUES արժեք, երեք VALUES արժեք, կամ նշում էինք դրանցից 10-ը՝ բաժանված ստորակետով: Սա հիմա ուղղակի հորիզոնական է: 1, 2, 4, 128. Երևում է, որ խմբաքանակի ներդիրը, որը գծված է կապույտ գույնով, նրան շատ ավելի լավ է զգում։ Այսինքն, երբ մեկ-մեկ տեղադրում ես կամ նույնիսկ չորսը միաժամանակ դնում ես, այն կրկնակի լավ է դառնում, պարզապես այն պատճառով, որ մենք մի փոքր ավելի խցկվել ենք ԱՐԺԵՔՆԵՐԻ մեջ: Ավելի քիչ EXECUTE գործողություններ:

COPY-ի օգտագործումը փոքր ծավալների վրա չափազանց անհեռանկարային է: Ես նույնիսկ առաջին երկուսի վրա չեմ նկարել: Նրանք գնում են դրախտ, այսինքն՝ այս կանաչ թվերը COPY-ի համար։

COPY-ը պետք է օգտագործվի, երբ դուք ունեք առնվազն հարյուր տող տվյալներ: Այս կապի բացման ծախսը մեծ է: Եվ, ճիշտն ասած, ես չեմ փորել այս ուղղությամբ: Ես օպտիմիզացրել եմ Batch-ը, բայց ոչ COPY:

Ի՞նչ անենք հետո: Մենք փորձեցինք այն: Մենք հասկանում ենք, որ մենք պետք է օգտագործենք կամ կառուցվածքներ, կամ խելացի բաղնիք, որը միավորում է մի քանի իմաստներ:

PostgreSQL-ը և JDBC-ն քամում են ամբողջ հյութը: Վլադիմիր Սիտնիկով

Ի՞նչ պետք է վերցնեք այսօրվա զեկույցից:

  • PreparedStatement-ը մեր ամեն ինչն է: Սա շատ բան է տալիս արտադրողականության համար: Այն առաջացնում է քսուքի մեծ փխրունություն:
  • Եվ դուք պետք է 6 անգամ կատարեք EXPLAIN ANALYZE:
  • Եվ մենք պետք է նոսրացնենք OFFSET 0-ը և հնարքները, ինչպիսիք են +0-ը, որպեսզի շտկենք մեր խնդրահարույց հարցումների մնացած տոկոսը:

Source: www.habr.com

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