PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

مان توهان کي صلاح ڏيان ٿو ته توهان ولاديمير سيٽنيڪوف جي شروعاتي 2016 جي رپورٽ جو ٽرانسڪرپٽ پڙهو ”پوسٽ گري ايس ايس ايل ۽ جي ڊي بي سي سڀ رس ڪڍي رهيا آهن“

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

منجهند جو سلام منهنجو نالو Vladimir Sitnikov آهي. مان 10 سالن کان NetCracker لاءِ ڪم ڪري رهيو آهيان. ۽ مان گهڻو ڪري پيداوار ۾ آهيان. جاوا سان لاڳاپيل هر شي، SQL سان لاڳاپيل هر شيء جيڪا مون کي پسند آهي.

۽ اڄ آئون ان بابت ڳالهائيندس جيڪو اسان ڪمپني ۾ محسوس ڪيو جڏهن اسان پوسٽ گري ايس ايس ايل کي ڊيٽابيس سرور طور استعمال ڪرڻ شروع ڪيو. ۽ اسان گهڻو ڪري جاوا سان ڪم ڪندا آهيون. پر جيڪو مان توهان کي اڄ ٻڌائڻ وارو آهيان اهو صرف جاوا بابت ناهي. جيئن مشق ڏيکاريو ويو آهي، اهو ٻين ٻولين ۾ پڻ ٿئي ٿو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اسان ڳالهائينداسين:

  • ڊيٽا نموني جي باري ۾.
  • ڊيٽا بچائڻ جي باري ۾.
  • ۽ ڪارڪردگي بابت پڻ.
  • ۽ پاڻيءَ جي هيٺان ريڪ بابت جيڪي اتي دفن ٿيل آهن.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته هڪ سادي سوال سان شروع ڪريون. اسان ٽيبل مان ھڪڙي قطار کي بنيادي ڪي جي بنياد تي چونڊيو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

ڊيٽابيس ساڳئي ميزبان تي واقع آهي. ۽ هي سڀ پوک 20 مليسيڪنڊ وٺندو آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اهي 20 مليسيڪنڊ تمام گهڻا آهن. جيڪڏهن توهان وٽ 100 اهڙيون درخواستون آهن، ته پوءِ توهان انهن درخواستن جي ذريعي في سيڪنڊ اسڪرول ڪرڻ ۾ وقت گذاريو، يعني اسان وقت ضايع ڪري رهيا آهيون.

اسان اهو ڪرڻ پسند نٿا ڪريون ۽ ڏسو ته ڇا بنياد اسان کي هن لاءِ پيش ڪري ٿو. ڊيٽابيس اسان کي سوالن تي عمل ڪرڻ لاءِ ٻه آپشن پيش ڪري ٿو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

پهريون اختيار هڪ سادي درخواست آهي. ان بابت ڇا سٺو آهي؟ حقيقت اها آهي ته اسان ان کي وٺي ۽ ان کي موڪليو، ۽ وڌيڪ ڪجھ به نه.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

ڊيٽابيس ۾ پڻ هڪ جديد سوال آهي، جيڪو وڌيڪ مشڪل آهي، پر وڌيڪ ڪارائتو آهي. توهان الڳ الڳ موڪلي سگهو ٿا parsing، execution، variable binding، وغيره لاءِ درخواست.

سپر توسيع سوال اهو آهي جيڪو اسان موجوده رپورٽ ۾ نه ڍڪينداسين. اسان، شايد، ڊيٽابيس مان ڪجهه چاهيون ٿا ۽ هڪ خواهش جي فهرست آهي جيڪا ڪنهن نه ڪنهن شڪل ۾ ٺاهي وئي آهي، يعني اهو آهي جيڪو اسان چاهيون ٿا، پر اهو هاڻي ۽ ايندڙ سال ۾ ناممڪن آهي. تنهن ڪري اسان صرف ان کي رڪارڊ ڪيو ۽ اسان مکيه ماڻهن کي ڇڪي وينداسين.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

۽ جيڪو اسان ڪري سگهون ٿا سادو سوال ۽ وڌايل سوال آهي.

هر طريقي جي باري ۾ خاص ڇا آهي؟

هڪ سادي سوال هڪ وقت جي عمل لاء سٺو آهي. هڪ دفعو ٿي ويو ۽ وساري ڇڏيو. ۽ مسئلو اهو آهي ته اهو بائنري ڊيٽا فارميٽ جي حمايت نٿو ڪري، يعني اهو ڪجهه اعلي ڪارڪردگي سسٽم لاء مناسب ناهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

توسيع ڪيل سوال - توهان کي تجزيي تي وقت بچائڻ جي اجازت ڏئي ٿي. اھو اھو آھي جيڪو اسان ڪيو ۽ استعمال ڪرڻ شروع ڪيو. هي واقعي، واقعي اسان جي مدد ڪئي. نه رڳو parsing تي بچت آهن. ڊيٽا جي منتقلي تي بچت آهي. بائنري فارميٽ ۾ ڊيٽا جي منتقلي تمام گهڻو ڪارائتو آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته مشق ڏانهن وڃو. هي اهو آهي جيڪو هڪ عام ايپليڪيشن وانگر ڏسڻ ۾ اچي ٿو. ٿي سگهي ٿو جاوا وغيره.

اسان بيان پيدا ڪيو. حڪم تي عمل ڪيو. ويجهو ٺاهي وئي. هتي غلطي ڪٿي آهي؟ ڇا مسئلو آهي؟ ڪو مسئلو ناهي. اھو اھو آھي جيڪو سڀني ڪتابن ۾ لکيل آھي. ائين ئي لکڻ گهرجي. جيڪڏھن توھان چاھيو ٿا وڌ ۾ وڌ ڪارڪردگي، ھن طرح لکو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

پر مشق ڏيکاريو ويو آهي ته اهو ڪم نٿو ڪري. ڇو؟ ڇو ته اسان وٽ هڪ "قريب" طريقو آهي. ۽ جڏهن اسان اهو ڪريون ٿا، ڊيٽابيس جي نقطي نظر کان اهو ظاهر ٿئي ٿو ته اهو هڪ تماڪ ڪندڙ وانگر آهي جيڪو ڊيٽابيس سان ڪم ڪري رهيو آهي. اسان چيو ته "PARSE EXECUTE DEALLOCATE".

هي سڀ اضافي تخليق ۽ بيانن جي لوڊشيڊنگ ڇو؟ ڪنهن کي به انهن جي ضرورت ناهي. پر عام طور تي ڇا ٿئي ٿو PreparedStatements ۾ اهو آهي ته جڏهن اسان انهن کي بند ڪندا آهيون، اهي ڊيٽابيس تي هر شي کي بند ڪندا آهن. اهو نه آهي جيڪو اسان چاهيون ٿا.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اسان چاهيون ٿا، صحتمند ماڻهن وانگر، بنيادي طور تي ڪم ڪرڻ لاء. اسان پنهنجو بيان هڪ ڀيرو ورتو ۽ تيار ڪيو، پوءِ ڪيترائي ڀيرا ان تي عمل ڪيو. حقيقت ۾، ڪيترائي ڀيرا - هي ايپليڪيشنن جي سڄي زندگي ۾ هڪ ڀيرو آهي - انهن کي پارس ڪيو ويو آهي. ۽ اسان مختلف RESTs تي ساڳيو بيان id استعمال ڪندا آهيون. هي اسان جو مقصد آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اسان اهو ڪيئن حاصل ڪري سگهون ٿا؟

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اهو تمام سادو آهي - بيانن کي بند ڪرڻ جي ڪا ضرورت ناهي. اسان ان کي هن طرح لکندا آهيون: "تيار ڪريو" "عمل".

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

جيڪڏهن اسان اهڙي ڪا شيءِ شروع ڪريون ٿا، ته پوءِ اهو واضح آهي ته ڪا شيءِ ڪنهن جاءِ تي وهندي. جيڪڏهن اهو واضح ناهي، توهان ڪوشش ڪري سگهو ٿا. اچو ته هڪ معيار لکون جيڪو هن سادي طريقي کي استعمال ڪري ٿو. هڪ بيان ٺاهيو. اسان ان کي ڊرائيور جي ڪجهه ورزن تي لانچ ڪيو ۽ ڳوليو ته اهو تمام جلدي حادثو ٿئي ٿو تمام جلدي ياداشت جي نقصان سان جيڪو ان وٽ هو.

اهو واضح آهي ته اهڙيون غلطيون آساني سان درست ڪيون وينديون آهن. مان ان بابت نه ڳالهائيندس. پر مان چوان ٿو ته نئون نسخو تمام تيز ڪم ڪري ٿو. طريقو بيوقوف آهي، پر اڃا به.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

ڪيئن صحيح ڪم ڪرڻ لاء؟ ان لاءِ اسان کي ڇا ڪرڻ گهرجي؟

حقيقت ۾، ايپليڪيشنون هميشه بيانن کي بند ڪن ٿيون. سڀني ڪتابن ۾ چوندا آھن ته بند ڪريو، ٻي صورت ۾ ياداشت لڪي ويندي.

۽ PostgreSQL کي خبر ناهي ته سوالن کي ڪيئن ڪيش ڪجي. اهو ضروري آهي ته هر سيشن پاڻ لاء هن ڪيش ٺاهي.

۽ اسان نه ٿا چاهيون ته پارس ڪرڻ تي وقت ضايع ڪرڻ.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

۽ هميشه وانگر اسان وٽ ٻه آپشن آهن.

پهريون آپشن اهو آهي ته اسان ان کي وٺون ٿا ۽ چئون ٿا ته اچو ته سڀ ڪجهه PgSQL ۾ لپيٽيون. اتي هڪ ڪيش آهي. اهو سڀ ڪجهه محفوظ ڪري ٿو. اهو وڏو ٻاهر ڦرندو. اسان اهو ڏٺو. اسان وٽ 100500 درخواستون آهن. ڪم نه ڪندو آهي. اسان دستي طور تي درخواستن کي طريقيڪار ۾ تبديل ڪرڻ تي متفق نه آهيون. نه نه.

اسان وٽ ھڪڙو ٻيو اختيار آھي - اھو وٺو ۽ ان کي پاڻ کي ڪٽيو. اسان ذريعن کي کوليو ۽ ڪٽڻ شروع ڪيو. اسان ڏٺو ۽ ڏٺو. اهو ظاهر ٿيو ته اهو ڪرڻ ڏکيو ناهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

اهو آگسٽ 2015 ۾ ظاهر ٿيو. هاڻي اتي هڪ وڌيڪ جديد نسخو آهي. ۽ هر شي عظيم آهي. اهو تمام سٺو ڪم ڪري ٿو ته اسان ايپليڪيشن ۾ ڪجھ به تبديل نه ڪندا آهيون. ۽ اسان PgSQL جي هدايت ۾ سوچڻ به بند ڪري ڇڏيو، يعني اهو اسان لاءِ ڪافي هو ته اسان سڀني مٿان ٿيندڙ خرچن کي تقريبن صفر تائين گھٽائي سگهون.

مطابق، سرور تيار ڪيل بيانن کي 5 هين عمل تي چالو ڪيو ويو آهي ته جيئن هر هڪ وقت جي درخواست تي ڊيٽابيس ۾ ميموري ضايع ٿيڻ کان بچڻ لاء.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

توھان پڇي سگھو ٿا - نمبر ڪٿي آھن؟ توهان ڇا حاصل ڪري رهيا آهيو؟ ۽ هتي آئون نمبر نه ڏيندس، ڇاڪاڻ ته هر درخواست پنهنجي پنهنجي آهي.

اسان جا سوال اهڙا هئا جو اسان OLTP سوالن کي پارس ڪرڻ تي اٽڪل 20 ملي سيڪنڊ خرچ ڪيو. عمل ڪرڻ لاءِ 0,5 مليسيڪنڊ هئا، پارس ڪرڻ لاءِ 20 مليسيڪنڊ. درخواست - 10 KiB ٽيڪسٽ، 170 لائنون منصوبا. هي هڪ OLTP درخواست آهي. اهو درخواست ڪري ٿو 1، 5، 10 لائينون، ڪڏهن ڪڏهن وڌيڪ.

پر اسان هرگز 20 مليسيڪنڊ ضايع ڪرڻ نٿا چاهيون. اسان ان کي 0 تائين گھٽايو. هر شي عظيم آهي.

توهان هتان کان ڇا وٺي سگهو ٿا؟ جيڪڏهن توهان وٽ جاوا آهي، ته پوء توهان ڊرائيور جو جديد نسخو وٺو ۽ خوش ٿيو.

جيڪڏهن توهان هڪ مختلف ٻولي ڳالهايو، پوء سوچيو - شايد توهان کي هن جي ضرورت آهي؟ ڇاڪاڻ ته آخري ٻوليءَ جي نقطي نظر کان، مثال طور، جيڪڏهن PL 8 يا توهان وٽ LibPQ آهي، ته پوءِ اهو توهان لاءِ واضح ناهي ته توهان وقت گذاري رهيا آهيو نه پر عملدرآمد تي، نه پر پارس ڪرڻ تي، ۽ اهو جانچڻ جي لائق آهي. ڪيئن؟ هر شي مفت آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

سواءِ ان جي ته ڪي خاميون ۽ ڪي خاصيتون آهن. ۽ اسان ان بابت هاڻي ڳالهائينداسين. گهڻو ڪري اهو صنعتي آثار قديمه جي باري ۾ هوندو، جيڪو اسان کي مليو، جيڪو اسان ڏٺو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

جيڪڏهن درخواست متحرڪ طور تي ٺاهي وئي آهي. ٿئي ٿو. ڪو ماڻهو تارن کي گڏ ڪري ٿو، نتيجي ۾ هڪ SQL سوال.

هو خراب ڇو آهي؟ اهو خراب آهي ڇاڪاڻ ته هر وقت اسان هڪ مختلف تار سان ختم ڪريون ٿا.

۽ هن مختلف اسٽرنگ جو هيش ڪوڊ ٻيهر پڙهڻ جي ضرورت آهي. اهو واقعي هڪ سي پي يو ڪم آهي - هڪ ڊگهي درخواست واري متن کي ڳولڻ به هڪ موجود هيش ۾ ايترو آسان ناهي. تنهن ڪري، نتيجو سادو آهي - درخواستون پيدا نه ڪريو. انھن کي ھڪڙي متغير ۾ ذخيرو ڪريو. ۽ خوش ٿيو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

ايندڙ مسئلو. ڊيٽا جا قسم اهم آهن. اهڙا ORMs آهن جيڪي چون ٿا ته اهو مسئلو ناهي ته ڪهڙي قسم جو NULL آهي، اتي ڪجهه قسم جو هجڻ ڏيو. جيڪڏهن Int، پوء اسان چوندا آهيون setInt. ۽ جيڪڏهن NULL، ته پوء ان کي هميشه VARCHAR ٿيڻ ڏيو. ۽ آخر ان سان ڪهڙو فرق پوي ٿو ته NULL ڇا آهي؟ ڊيٽابيس پاڻ کي سڀ ڪجھ سمجھندو. ۽ هي تصوير ڪم نٿو ڪري.

عملي طور تي، ڊيٽابيس کي ڪابه پرواهه ناهي. جيڪڏهن توهان پهريون ڀيرو چيو ته هي هڪ نمبر آهي، ۽ ٻيو ڀيرو توهان چيو آهي ته اهو هڪ VARCHAR آهي، ته پوءِ سرور جي تيار ڪيل بيانن کي ٻيهر استعمال ڪرڻ ناممڪن آهي. ۽ انهي صورت ۾، اسان کي پنهنجو بيان ٻيهر ٺاهڻو پوندو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

جيڪڏهن توهان ساڳئي سوال تي عمل ڪري رهيا آهيو، پڪ ڪريو ته توهان جي ڪالمن ۾ ڊيٽا جا قسم پريشان نه آهن. توھان کي NULL لاءِ ڌيان ڏيڻ جي ضرورت آھي. اها هڪ عام غلطي آهي جيڪا اسان اڳ ۾ استعمال ڪرڻ شروع ڪئي هئي PreparedStatements

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

ٺيڪ، چالو. شايد اهي ڊرائيور وٺي ويا. ۽ پيداوار گهٽجي وئي. شيون خراب ٿي ويون.

اهو ڪيئن ٿو ٿئي؟ ڇا هي هڪ بگ يا خاصيت آهي؟ بدقسمتي سان، اهو سمجهڻ ممڪن نه هو ته اهو هڪ بگ آهي يا هڪ خاصيت آهي. پر هن مسئلي کي ٻيهر پيدا ڪرڻ لاء هڪ تمام سادو منظر آهي. هوء مڪمل طور تي غير متوقع طور تي اسان تي حملو ڪيو. ۽ اهو هڪ ٽيبل مان لفظي نموني نموني تي مشتمل آهي. اسان وٽ، يقينا، اهڙيون وڌيڪ درخواستون هيون. ضابطي جي طور تي، انهن ۾ ٻه يا ٽي ٽيبل شامل آهن، پر اتي هڪ پلے بیک منظر آهي. توهان جي ڊيٽابيس مان ڪو به نسخو وٺو ۽ ان کي راند ڪريو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

نقطو اهو آهي ته اسان وٽ ٻه ڪالمن آهن، جن مان هر هڪ ترتيب ڏنل آهي. هڪ NULL ڪالمن ۾ هڪ ملين قطارون آهن. ۽ ٻئي ڪالم ۾ صرف 20 لائينون آهن. جڏهن اسان بغير پابند متغيرن تي عمل ڪريون ٿا، هر شي سٺو ڪم ڪري ٿو.

جيڪڏهن اسان پابند متغيرن سان عمل ڪرڻ شروع ڪندا آهيون، يعني اسين "؟" يا ”$1“ اسان جي درخواست لاءِ، اسان آخر ڇا حاصل ڪريون؟

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

پهرين عمل جي توقع آهي. ٻيو ٿورو تيز آهي. ڪا شيءِ رکيل هئي. ٽيون، چوٿون، پنجون. پوء ڌماڪو - ۽ اهڙي شيء. ۽ بدترين شيء اها آهي ته اهو ڇهين اعدام تي ٿئي ٿو. ڪنهن کي خبر هئي ته اهو سمجهڻ لاءِ ڇهن موتين کي انجام ڏيڻ ضروري هو ته اصل عملدرآمد پلان ڇا هو؟

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

قصوروار ڪير آهي؟ ڇا ٿيو؟ ڊيٽابيس ۾ اصلاح شامل آهي. ۽ اهو لڳي ٿو ته عام ڪيس لاءِ بهتر ڪيو وڃي. ۽، مطابق، ڪجهه نقطي تي شروع ڪندي، هوء هڪ عام منصوبي کي تبديل ڪري ٿي، جيڪا بدقسمتي سان، مختلف ٿي سگهي ٿي. اهو ساڳيو ٿي سگهي ٿو، يا اهو مختلف ٿي سگهي ٿو. ۽ اتي ڪجھ قسم جي حد قدر آھي جيڪا ھن رويي جي ڪري ٿي.

توهان ان بابت ڇا ڪري سگهو ٿا؟ هتي، يقينا، ڪنهن به شيء کي فرض ڪرڻ کان وڌيڪ ڏکيو آهي. ھڪڙو سادو حل آھي جيڪو اسان استعمال ڪندا آھيون. هي +0 آهي، OFFSET 0. يقيناً توهان اهڙن حلن کي ڄاڻو ٿا. اسان صرف ان کي وٺو ۽ شامل ڪريو "+0" درخواست ۾ ۽ سڀ ڪجھ ٺيڪ آهي. مان توهان کي بعد ۾ ڏيکاريندس.

۽ ھڪڙو ٻيو اختيار آھي - منصوبن کي وڌيڪ احتياط سان ڏسو. ڊولپر کي نه رڳو هڪ درخواست لکڻ گهرجي، پر اهو پڻ چوڻ گهرجي ته "تجزيو بيان ڪريو" 6 ڀيرا. جيڪڏهن اهو 5 آهي، اهو ڪم نه ڪندو.

۽ ٽيون اختيار آھي - pgsql-hackers ڏانھن خط لکو. مون لکيو، تنهن هوندي، اهو اڃا تائين واضح ناهي ته اهو هڪ بگ آهي يا هڪ خاصيت آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

جڏهن اسان سوچي رهيا آهيون ته ڇا هي هڪ بگ آهي يا هڪ خاصيت آهي، اچو ته ان کي درست ڪريون. اچو ته اسان جي درخواست وٺو ۽ "+0" شامل ڪريو. سڀ ڪجھ ٺيڪ آهي. ٻه علامتون ۽ توهان کي سوچڻ جي ضرورت ناهي ته اهو ڪيئن آهي يا اهو ڇا آهي. تمام سادو. اسان صرف ڊيٽابيس کي هن ڪالمن تي انڊيڪس استعمال ڪرڻ کان منع ڪيو آهي. اسان وٽ "+0" ڪالمن تي انڊيڪس نه آهي ۽ اهو ئي آهي، ڊيٽابيس انڊيڪس استعمال نٿو ڪري، سڀ ڪجهه ٺيڪ آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

هي آهي 6 جو قاعدو وضاحت. ھاڻي موجوده ورزن ۾ توھان کي ڪرڻو پوندو 6 ڀيرا جيڪڏھن توھان وٽ پابند متغير آھي. جيڪڏهن توهان وٽ پابند متغير نه آهي، اهو آهي جيڪو اسان ڪندا آهيون. ۽ آخر ۾ اهو خاص طور تي هي درخواست آهي جيڪو ناڪام ٿيو. اها ڪا مشڪل ڳالهه ناهي.

اهو لڳي ٿو، ڪيترو ممڪن آهي؟ هتي هڪ بگ، اتي هڪ بگ. حقيقت ۾، بگ هر جڳهه آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته هڪ ويجهي نظر وٺو. مثال طور، اسان وٽ ٻه اسڪيمون آهن. اسڪيم A سان ٽيبل S ۽ ڊراگرام B ٽيبل S سان. سوال - ٽيبل مان ڊيٽا چونڊيو. هن معاملي ۾ اسان کي ڇا ٿيندو؟ اسان کي غلطي ٿيندي. اسان وٽ مٿيون سڀ شيون هونديون. قاعدو آهي - هڪ بگ هر جڳهه آهي، اسان وٽ مٿيون سڀ شيون هونديون.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

هاڻي سوال آهي: "ڇو؟" اهو لڳي ٿو ته اتي دستاويز آهي ته جيڪڏهن اسان وٽ هڪ اسڪيما آهي، پوء اتي هڪ "search_path" متغير آهي جيڪو اسان کي ٻڌائي ٿو ته ٽيبل کي ڪٿي ڳولڻ لاء. اهو لڳي ٿو ته اتي هڪ variable آهي.

ڇا مسئلو آهي؟ مسئلو اهو آهي ته سرور جي تيار ڪيل بيانن کي شڪ ناهي ته ڳولا_پيٿ ڪنهن جي طرفان تبديل ٿي سگهي ٿي. هي قدر رهي ٿو، جيئن ته هو، ڊيٽابيس لاءِ مستقل. ۽ ڪجھ حصا شايد نئين معني نه کڻندا.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

يقينن، اهو ان نسخي تي منحصر آهي جنهن تي توهان جاچ ڪري رهيا آهيو. ان تي منحصر آهي ته توهان جي جدولن ۾ ڪيتري حد تائين فرق آهي. ۽ نسخو 9.1 صرف پراڻي درخواستن تي عمل ڪندو. نوان ورجن شايد بگ کي پڪڙي سگھن ٿا ۽ توهان کي ٻڌائي ٿو ته توهان وٽ هڪ بگ آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

سيٽ سرچ_پاٿ + سرور تيار ڪيل بيان =
ڪيشڊ پلان کي تبديل نه ڪرڻ گهرجي نتيجن جو قسم

ان جو علاج ڪيئن ڪجي؟ اتي ھڪڙو سادو طريقو آھي - اھو نه ڪريو. ائپليڪيشن ھلائڻ دوران search_path کي تبديل ڪرڻ جي ڪا ضرورت ناھي. جيڪڏھن توھان تبديل ڪريو، اھو بھتر آھي ھڪڙو نئون ڪنيڪشن ٺاھيو.

توھان بحث ڪري سگھو ٿا، يعني کليل، بحث، شامل ڪريو. ٿي سگهي ٿو اسان ڊيٽابيس ڊولپرز کي قائل ڪري سگهون ٿا ته جڏهن ڪو ماڻهو قدر تبديل ڪري، ڊيٽابيس کي ڪلائنٽ کي هن بابت ٻڌايو وڃي: "ڏس، توهان جي قيمت هتي اپڊيٽ ڪئي وئي آهي. ٿي سگهي ٿو توهان کي بيانن کي ري سيٽ ڪرڻ ۽ انهن کي ٻيهر ٺاهڻ جي ضرورت آهي؟ هاڻي ڊيٽابيس ڳجهي طريقي سان عمل ڪري ٿو ۽ ڪنهن به طريقي سان رپورٽ نه ڪندو آهي ته بيان اندر اندر تبديل ٿي ويا آهن.

۽ مان ٻيهر زور ڏيندس - اهو ڪجهه آهي جيڪو جاوا لاءِ عام ناهي. اسان ساڳئي شيء کي PL/pgSQL ۾ هڪ کان هڪ ڏسندا سين. پر اهو اتي ٻيهر پيدا ڪيو ويندو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته ڪجھ وڌيڪ ڊيٽا جي چونڊ جي ڪوشش ڪريو. اسان چونڊيو ۽ چونڊيو. اسان وٽ هڪ ٽيبل آهي هڪ لک قطارن سان. هر لڪير هڪ kilobyte آهي. تقريبن هڪ گيگا بائيٽ ڊيٽا. ۽ اسان وٽ 128 ميگا بائيٽ جي جاوا مشين ۾ ڪم ڪندڙ ياداشت آهي.

اسان، جيئن سڀني ڪتابن ۾ سفارش ڪئي وئي آهي، وهڪرو پروسيسنگ استعمال ڪريو. اهو آهي، اسان نتيجو سيٽ کوليو ۽ اتان جي ڊيٽا کي ٿوري دير سان پڙهو. ڇا اهو ڪم ڪندو؟ ڇا اهو ياداشت مان گر ٿيندو؟ ٿورڙو پڙهندؤ؟ اچو ته ڊيٽابيس ۾ اعتماد رکون، اچو ته پوسٽ گريس تي اعتماد رکون. اسان ان تي يقين نه ٿا ڪريون. ڇا اسان ختم ٿي ويندا آف ميموري؟ ڪنهن OutOfMemory جو تجربو ڪيو؟ ان کان پوء ڪير ان کي درست ڪرڻ جو انتظام ڪيو؟ ڪو ماڻهو ان کي درست ڪرڻ لاء منظم.

جيڪڏهن توهان وٽ هڪ لک قطارون آهن، توهان صرف چونڊي ۽ چونڊي نٿا سگهو. OFFSET/LIMIT گھربل آھي. هن اختيار لاء ڪير آهي؟ ۽ ڪير آٽو ڪميٽ سان کيڏڻ جي حق ۾ آهي؟

هتي، عام طور تي، سڀ کان وڌيڪ اڻڄاتل اختيار درست ٿي ويو. ۽ جيڪڏھن توھان اوچتو بند ڪريو autoCommit، اھو مدد ڪندو. ائين ڇو آهي؟ سائنس ان بابت نه ڄاڻندي آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

پر ڊفالٽ طور، پوسٽ گريس ڊيٽابيس سان ڳنڍڻ وارا سڀئي گراهڪ سڄي ڊيٽا آڻيندا آهن. PgJDBC هن سلسلي ۾ ڪو به استثنا نه آهي؛ اهو سڀ قطار چونڊيندو آهي.

هتي FetchSize موضوع تي هڪ تبديلي آهي، يعني توهان هڪ الڳ بيان جي سطح تي چئي سگهو ٿا ته هتي، مهرباني ڪري 10، 50 ذريعي ڊيٽا چونڊيو. پر اهو ڪم نه ڪندو جيستائين توهان خودڪار ڪم کي بند نه ڪندا. بند ڪيو autoCommit - اهو ڪم ڪرڻ شروع ڪري ٿو.

پر ڪوڊ ذريعي وڃڻ ۽ سيٽنگ سيٽ فيچ سيز هر جڳهه تي تڪليف آهي. تنهن ڪري، اسان هڪ سيٽنگ ٺاهي جيڪا سڄي ڪنيڪشن لاء ڊفالٽ قيمت چوندا.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

ائين ئي چيوسين. پيٽرولر کي ترتيب ڏنو ويو آهي. ۽ اسان کي ڇا مليو؟ جيڪڏهن اسان ننڍي مقدار کي چونڊيندا آهيون، مثال طور، اسان هڪ وقت ۾ 10 قطارون چونڊيندا آهيون، پوءِ اسان وٽ تمام وڏا مٿيون خرچ آهن. تنهن ڪري، هن قدر جي باري ۾ هڪ سئو مقرر ڪيو وڃي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

مثالي طور، يقينا، توهان کي اڃا تائين اهو سکڻو پوندو ته ان کي بائيٽ ۾ ڪيئن محدود ڪجي، پر ترڪيب هي آهي: defaultRowFetchSize کي هڪ سئو کان وڌيڪ سيٽ ڪريو ۽ خوش ٿيو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته ڊيٽا داخل ڪرڻ لاء اڳتي وڌو. داخل ڪرڻ آسان آهي، اتي مختلف آپشن آهن. مثال طور، INSERT، VALUES. هي هڪ سٺو اختيار آهي. توھان چئي سگھو ٿا ”انسرٽ چونڊيو“. عملي طور تي اهو ساڳيو آهي. ڪارڪردگي ۾ ڪوبه فرق ناهي.

ڪتاب چون ٿا ته توهان کي بيچ بيان تي عمل ڪرڻ جي ضرورت آهي، ڪتابن جو چوڻ آهي ته توهان ڪيترن ئي قوسن سان وڌيڪ پيچيده حڪم جاري ڪري سگهو ٿا. ۽ Postgres ۾ هڪ شاندار خصوصيت آهي - توهان ڪري سگهو ٿا COPY، يعني ان کي تيز ڪريو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

جيڪڏهن توهان ان کي ماپ ڪري سگهو ٿا، توهان ٻيهر ڪجهه دلچسپ دريافت ڪري سگهو ٿا. اسان اهو ڪيئن ڪم ڪرڻ چاهيون ٿا؟ اسان چاهيون ٿا ته پارس نه ڪريو ۽ غير ضروري حڪمن تي عمل نه ڪيو وڃي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

عملي طور تي، TCP اسان کي ائين ڪرڻ جي اجازت نٿو ڏئي. جيڪڏهن ڪلائنٽ هڪ درخواست موڪلڻ ۾ مصروف آهي، ته ڊيٽابيس اسان کي جواب موڪلڻ جي ڪوشش ۾ درخواستون نه پڙهي. آخري نتيجو اهو آهي ته ڪلائنٽ ڊيٽابيس جي درخواست کي پڙهڻ لاء انتظار ڪري ٿو، ۽ ڊيٽابيس جو انتظار ڪري ٿو ڪلائنٽ جو جواب پڙهڻ لاء.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

۽ تنهن ڪري ڪلائنٽ وقتي طور تي هڪ هم وقت سازي پيڪٽ موڪلڻ تي مجبور آهي. اضافي نيٽ ورڪ رابطي، وقت جو اضافي ضايع.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov۽ وڌيڪ اسان انهن کي شامل ڪيو، اهو وڌيڪ خراب ٿيندو. ڊرائيور ڪافي مايوسي وارو آهي ۽ انهن کي اڪثر شامل ڪري ٿو، تقريبن هڪ ڀيرو هر 200 لائينون، لائينن جي سائيز جي لحاظ کان، وغيره.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

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

اهو ٿئي ٿو ته توهان صرف هڪ لڪير کي درست ڪريو ۽ هر شيء 10 ڀيرا تيز ٿي ويندي. ٿئي ٿو. ڇو؟ هميشه وانگر، هن وانگر هڪ مسلسل اڳ ۾ ئي استعمال ڪيو ويو آهي. ۽ قدر "128" جو مطلب بيچنگ استعمال ڪرڻ نه آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

جاوا microbenchmark هارنس

اهو سٺو آهي ته هي سرڪاري ورزن ۾ شامل نه ڪيو ويو. رليز شروع ٿيڻ کان اڳ دريافت ڪيو. سڀ معنيٰ جيڪي مان ڏيان ٿو جديد نسخن تي ٻڌل آهن.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اچو ته ان تي ڪوشش ڪريون. اسان InsertBatch سادو ماپون ٿا. اسان InsertBatch ڪيترائي ڀيرا ماپون ٿا، يعني ساڳي شيءِ، پر اتي ڪيترائي قدر آھن. مشڪل حرڪت. هرڪو اهو نٿو ڪري سگهي، پر اهو هڪ سادو قدم آهي، COPY کان گهڻو آسان.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

توهان ڪاپي ڪري سگهو ٿا.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

۽ توھان ھي ڪري سگھوٿا اڏاوتن تي. استعمال ڪندڙ جي ڊفالٽ قسم جو اعلان ڪريو، صف کي پاس ڪريو ۽ سڌو سنئون ٽيبل تي داخل ڪريو.

جيڪڏهن توهان لنڪ کوليندا آهيو: pgjdbc/ubenchmsrk/InsertBatch.java، پوء اهو ڪوڊ GitHub تي آهي. توھان ڏسي سگھوٿا خاص طور تي ڪھڙي درخواستون اتي پيدا ڪيون ويون آھن. هن سان فرق نٿو پئي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اسان لانچ ڪيو. ۽ پهرين شيء جيڪا اسان محسوس ڪئي هئي ته بيچ استعمال نه ڪرڻ بلڪل ناممڪن آهي. سڀئي بيچنگ جا آپشن صفر آھن، يعني ھڪڙي وقت جي عمل جي مقابلي ۾ عملدرآمد جو وقت عملي طور تي صفر آھي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اسان ڊيٽا داخل ڪريون ٿا. اهو هڪ تمام سادو ٽيبل آهي. ٽي ڪالمن. ۽ اسان هتي ڇا ٿا ڏسو؟ اسان ڏسون ٿا ته اهي سڀئي ٽي اختيار تقريبن برابر آهن. ۽ COPY، يقينا، بهتر آهي.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

اهو آهي جڏهن اسان ٽڪر داخل ڪندا آهيون. جڏهن اسان چيو ته هڪ VALUES قدر، ٻه VALUES قدر، ٽي VALUES قدر، يا اسان انهن مان 10 کي ڪاما سان الڳ ڪيو. اهو هاڻي صرف افقي آهي. 1، 2، 4، 128. اهو ڏسي سگھجي ٿو ته بيچ داخل، جيڪو نيري رنگ ۾ ٺهيل آهي، هن کي تمام گهڻو بهتر محسوس ڪري ٿو. اهو آهي، جڏهن توهان هڪ وقت ۾ هڪ داخل ڪيو يا ايستائين جڏهن توهان هڪ وقت ۾ چار داخل ڪيو، اهو ٻه ڀيرا سٺو ٿيندو، صرف ان ڪري ته اسان VALUES ۾ ٿورو وڌيڪ وڌايو. گھٽ EXECUTE آپريشن.

ننڍي مقدار تي COPY استعمال ڪرڻ انتهائي ناپسنديده آهي. مون پهرين ٻن تي به نه ٺهيو. اهي جنت ڏانهن ويندا آهن، يعني اهي سائي نمبر COPY لاءِ.

COPY استعمال ٿيڻ گھرجي جڏھن توھان وٽ گھٽ ۾ گھٽ سؤ قطارون ڊيٽا آھن. هن ڪنيڪشن کي کولڻ جي اوور هيڊ وڏي آهي. ۽، ايماندار ٿيڻ لاء، مون هن هدايت ۾ نه کڙو ڪيو. مون بيچ کي بهتر ڪيو، پر ڪاپي نه.

اسان اڳتي ڇا ڪريون؟ اسان ان تي ڪوشش ڪئي. اسان سمجھون ٿا ته اسان کي يا ته ڍانچو استعمال ڪرڻ جي ضرورت آھي يا ھڪ ھوشيار بيٿ جيڪو ڪيترن ئي معنائن کي گڏ ڪري ٿو.

PostgreSQL ۽ JDBC سڀ رس ڪڍي ڇڏيندا آهن. Vladimir Sitnikov

توهان کي اڄ جي رپورٽ مان ڇا وٺڻ گهرجي؟

  • PreparedStatement اسان جو سڀ ڪجهه آهي. هي پيداوار لاء تمام گهڻو ڏئي ٿو. اهو عطر ۾ هڪ وڏو فلاپ پيدا ڪري ٿو.
  • ۽ توھان کي ڪرڻو پوندو وضاحت جو تجزيو 6 ڀيرا.
  • ۽ اسان کي OFFSET 0 کي گھٽائڻو پوندو، ۽ +0 جھڙين چالن کي درست ڪرڻ لاءِ اسان جي مشڪلاتي سوالن جي باقي سيڪڙو کي درست ڪرڻ لاءِ.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو