PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

میرا مشورہ ہے کہ آپ Vladimir Sitnikov کی ابتدائی 2016 کی رپورٹ کا ٹرانسکرپٹ پڑھیں "PostgreSQL اور JDBC سارا رس نچوڑ رہے ہیں"

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

صبح بخیر میرا نام ولادیمیر سیٹنکوف ہے۔ میں NetCracker کے لیے 10 سال سے کام کر رہا ہوں۔ اور میں زیادہ تر پیداوری میں ہوں۔ جاوا سے متعلق ہر چیز، ایس کیو ایل سے متعلق ہر چیز مجھے پسند ہے۔

اور آج میں اس کے بارے میں بات کروں گا کہ کمپنی میں ہمیں کیا سامنا کرنا پڑا جب ہم نے PostgreSQL کو بطور ڈیٹا بیس سرور استعمال کرنا شروع کیا۔ اور ہم زیادہ تر جاوا کے ساتھ کام کرتے ہیں۔ لیکن آج جو میں آپ کو بتانے جا رہا ہوں وہ صرف جاوا کے بارے میں نہیں ہے۔ جیسا کہ عملی طور پر دکھایا گیا ہے، یہ دوسری زبانوں میں بھی ہوتا ہے۔

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 تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آئیے پریکٹس کی طرف بڑھیں۔ یہ ایک عام ایپلی کیشن کی طرح لگتا ہے۔ یہ جاوا وغیرہ ہو سکتا ہے۔

ہم نے بیان تیار کیا۔ حکم پر عمل کیا۔ قریب بنایا۔ یہاں غلطی کہاں ہے؟ مسئلہ کیا ہے؟ کوئی مسئلہ نہیں. تمام کتابوں میں یہی کہا گیا ہے۔ اس طرح لکھنا چاہیے۔ اگر آپ زیادہ سے زیادہ کارکردگی چاہتے ہیں تو اس طرح لکھیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

لیکن مشق سے پتہ چلتا ہے کہ یہ کام نہیں کرتا ہے۔ کیوں؟ کیونکہ ہمارے پاس "قریبی" طریقہ ہے۔ اور جب ہم یہ کرتے ہیں، ڈیٹا بیس کے نقطہ نظر سے یہ پتہ چلتا ہے کہ یہ ڈیٹا بیس کے ساتھ کام کرنے والے سگریٹ نوشی کی طرح ہے۔ ہم نے کہا "PARSE EXECUTE DEALLOCATE"۔

یہ سب اضافی تخلیق اور بیانات کی اتار چڑھاؤ کیوں؟ کسی کو ان کی ضرورت نہیں۔ لیکن جو کچھ عام طور پر PreparedStatements میں ہوتا ہے وہ یہ ہے کہ جب ہم انہیں بند کرتے ہیں، تو وہ ڈیٹا بیس پر موجود ہر چیز کو بند کر دیتے ہیں۔ یہ وہ نہیں ہے جو ہم چاہتے ہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

ہم صحت مند لوگوں کی طرح بیس کے ساتھ کام کرنا چاہتے ہیں۔ ہم نے اپنا بیان ایک بار لیا اور تیار کیا، پھر کئی بار اس پر عمل کیا۔ درحقیقت، کئی بار - یہ ایپلی کیشنز کی پوری زندگی میں ایک بار ہے - ان کی تجزیہ کی گئی ہے۔ اور ہم مختلف RESTs پر ایک ہی اسٹیٹمنٹ آئی ڈی استعمال کرتے ہیں۔ یہ ہمارا مقصد ہے۔

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 تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آپ پوچھ سکتے ہیں - نمبر کہاں ہیں؟ آپ کیا حاصل کر رہے ہیں؟ اور یہاں میں نمبر نہیں دوں گا، کیونکہ ہر درخواست کی اپنی ہوتی ہے۔

ہمارے سوالات ایسے تھے کہ ہم نے OLTP سوالات کو پارس کرنے میں تقریباً 20 ملی سیکنڈ خرچ کیے۔ عمل درآمد کے لیے 0,5 ملی سیکنڈ، تجزیہ کرنے کے لیے 20 ملی سیکنڈز تھے۔ درخواست - متن کا 10 KiB، پلان کی 170 لائنیں۔ یہ OLTP کی درخواست ہے۔ یہ 1، 5، 10 لائنوں کی درخواست کرتا ہے، کبھی کبھی زیادہ۔

لیکن ہم 20 ملی سیکنڈ بالکل بھی ضائع نہیں کرنا چاہتے تھے۔ ہم نے اسے کم کر کے 0 کر دیا۔ سب کچھ بہت اچھا ہے۔

تم یہاں سے کیا لے جا سکتے ہو؟ اگر آپ کے پاس جاوا ہے، تو آپ ڈرائیور کا جدید ورژن لیں اور خوش ہوں۔

اگر آپ ایک مختلف زبان بولتے ہیں، تو سوچیں - شاید آپ کو بھی اس کی ضرورت ہے؟ کیونکہ حتمی زبان کے نقطہ نظر سے، مثال کے طور پر، اگر PL 8 یا آپ کے پاس LibPQ ہے، تو یہ آپ کے لیے واضح نہیں ہے کہ آپ عمل درآمد پر نہیں، تجزیہ کرنے پر وقت صرف کر رہے ہیں، اور یہ جانچنے کے قابل ہے۔ کیسے؟ سب کچھ مفت ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

سوائے اس کے کہ غلطیاں اور کچھ خصوصیات ہیں۔ اور ہم ابھی ان کے بارے میں بات کریں گے۔ اس میں سے زیادہ تر صنعتی آثار قدیمہ کے بارے میں ہو گا، اس کے بارے میں جو ہم نے پایا، کیا ہم نے دیکھا۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اگر درخواست متحرک طور پر تیار کی جاتی ہے۔ یہ ہوتا ہے. کوئی شخص تاروں کو ایک ساتھ چپکاتا ہے، جس کے نتیجے میں SQL استفسار ہوتا ہے۔

وہ برا کیوں ہے؟ یہ برا ہے کیونکہ ہر بار ہم ایک مختلف تار کے ساتھ ختم ہوتے ہیں۔

اور اس مختلف سٹرنگ کے ہیش کوڈ کو دوبارہ پڑھنے کی ضرورت ہے۔ یہ واقعی ایک CPU کام ہے - یہاں تک کہ موجودہ ہیش میں بھی طویل درخواست کا متن تلاش کرنا اتنا آسان نہیں ہے۔ لہذا، نتیجہ آسان ہے - درخواستیں پیدا نہ کریں۔ انہیں ایک متغیر میں اسٹور کریں۔ اور خوشیاں منائیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اگلا مسئلہ۔ ڈیٹا کی اقسام اہم ہیں۔ ایسے ORMs ہیں جو کہتے ہیں کہ اس سے کوئی فرق نہیں پڑتا ہے کہ 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 ہے، 0 آف سیٹ۔ یقیناً آپ ایسے حل جانتے ہیں۔ ہم صرف اسے لیتے ہیں اور درخواست میں "+0" شامل کرتے ہیں اور سب کچھ ٹھیک ہے۔ میں تمہیں بعد میں دکھاؤں گا۔

اور ایک اور آپشن ہے - منصوبوں کو زیادہ احتیاط سے دیکھیں۔ ڈویلپر کو نہ صرف درخواست لکھنی چاہیے بلکہ 6 بار "تجزیہ کی وضاحت" بھی کہنا چاہیے۔ اگر یہ 5 ہے تو یہ کام نہیں کرے گا۔

اور تیسرا آپشن ہے - pgsql-hackers کو خط لکھیں۔ میں نے لکھا، تاہم، یہ ابھی تک واضح نہیں ہے کہ یہ بگ ہے یا فیچر۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

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

جب ہم سوچ رہے ہیں کہ آیا یہ ایک بگ ہے یا کوئی خصوصیت، آئیے اسے ٹھیک کریں۔ آئیے ہماری درخواست لیں اور "+0" شامل کریں۔ سب کچھ ٹھیک ہے. دو علامتیں اور آپ کو یہ سوچنے کی بھی ضرورت نہیں ہے کہ یہ کیسا ہے یا کیا ہے۔ بہت آسان. ہم نے صرف ڈیٹا بیس کو اس کالم پر انڈیکس استعمال کرنے سے منع کیا ہے۔ ہمارے پاس "+0" کالم پر انڈیکس نہیں ہے اور بس، ڈیٹا بیس انڈیکس کا استعمال نہیں کرتا، سب کچھ ٹھیک ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

یہ 6 کا اصول ہے۔ اب موجودہ ورژن میں آپ کو یہ 6 بار کرنا ہوگا اگر آپ کے پاس متغیرات ہیں۔ اگر آپ کے پاس پابند متغیرات نہیں ہیں تو ہم یہی کرتے ہیں۔ اور آخر میں یہ بالکل وہی درخواست ہے جو ناکام ہوجاتی ہے۔ یہ کوئی مشکل بات نہیں ہے۔

ایسا لگتا ہے، کتنا ممکن ہے؟ یہاں ایک کیڑا، وہاں ایک کیڑا۔ اصل میں، بگ ہر جگہ ہے.

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آئیے قریب سے دیکھیں۔ مثال کے طور پر، ہمارے پاس دو اسکیما ہیں۔ ٹیبل S کے ساتھ اسکیم A اور ٹیبل S کے ساتھ خاکہ B۔ سوال - ٹیبل سے ڈیٹا منتخب کریں۔ اس معاملے میں ہمارے پاس کیا ہوگا؟ ہم سے غلطی ہو گی۔ ہمارے پاس اوپر کی تمام چیزیں ہوں گی۔ اصول یہ ہے کہ - ایک بگ ہر جگہ ہے، ہمارے پاس مندرجہ بالا سبھی چیزیں ہوں گی۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اب سوال یہ ہے: "کیوں؟" ایسا لگتا ہے کہ دستاویزات موجود ہیں کہ اگر ہمارے پاس اسکیما ہے، تو وہاں ایک "search_path" متغیر ہے جو ہمیں بتاتا ہے کہ ٹیبل کو کہاں تلاش کرنا ہے۔ ایسا لگتا ہے کہ ایک متغیر ہے۔

مسئلہ کیا ہے؟ مسئلہ یہ ہے کہ سرور سے تیار کردہ بیانات میں یہ شبہ نہیں ہے کہ search_path کسی کے ذریعہ تبدیل کیا جاسکتا ہے۔ یہ قدر ڈیٹا بیس کے لیے مستقل رہتی ہے، جیسا کہ یہ تھی۔ اور کچھ حصے نئے معنی نہیں اٹھا سکتے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

یقینا، یہ اس ورژن پر منحصر ہے جس کی آپ جانچ کر رہے ہیں۔ اس بات پر منحصر ہے کہ آپ کی میزیں کتنی سنجیدگی سے مختلف ہیں۔ اور ورژن 9.1 پرانی درخواستوں پر عمل درآمد کرے گا۔ نئے ورژن بگ پکڑ سکتے ہیں اور آپ کو بتا سکتے ہیں کہ آپ کے پاس ایک بگ ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

تلاش_پاتھ + سرور سے تیار کردہ بیانات = سیٹ کریں۔
کیشڈ پلان کو نتیجہ کی قسم کو تبدیل نہیں کرنا چاہیے۔

اس کا علاج کیسے کریں؟ ایک سادہ سا نسخہ ہے - ایسا مت کرو۔ ایپلی کیشن کے چلنے کے دوران search_path کو تبدیل کرنے کی ضرورت نہیں ہے۔ اگر آپ تبدیل کرتے ہیں تو، نیا کنکشن بنانا بہتر ہے.

آپ بحث کر سکتے ہیں، یعنی کھولیں، بحث کریں، شامل کریں۔ ہو سکتا ہے کہ ہم ڈیٹابیس ڈویلپرز کو قائل کر سکیں کہ جب کوئی کوئی ویلیو بدلتا ہے تو ڈیٹا بیس کو کلائنٹ کو اس بارے میں بتانا چاہیے: "دیکھو، آپ کی ویلیو یہاں اپ ڈیٹ کر دی گئی ہے۔ ہوسکتا ہے کہ آپ کو بیانات کو دوبارہ ترتیب دینے اور انہیں دوبارہ بنانے کی ضرورت ہو؟ اب ڈیٹا بیس خفیہ طور پر برتاؤ کرتا ہے اور کسی بھی طرح سے رپورٹ نہیں کرتا ہے کہ بیانات اندر سے کہیں بدل گئے ہیں۔

اور میں دوبارہ زور دوں گا - یہ وہ چیز ہے جو جاوا کے لیے عام نہیں ہے۔ ہم اسی چیز کو PL/pgSQL میں ایک سے ایک دیکھیں گے۔ لیکن اسے وہاں دوبارہ پیش کیا جائے گا۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آئیے کچھ اور ڈیٹا سلیکشن کی کوشش کرتے ہیں۔ ہم منتخب کرتے ہیں اور منتخب کرتے ہیں. ہمارے پاس دس لاکھ قطاروں والی میز ہے۔ ہر لائن ایک کلو بائٹ ہے۔ تقریباً ایک گیگا بائٹ ڈیٹا۔ اور ہمارے پاس جاوا مشین میں 128 میگا بائٹس کی ورکنگ میموری ہے۔

ہم، جیسا کہ تمام کتابوں میں تجویز کیا گیا ہے، اسٹریم پروسیسنگ کا استعمال کرتے ہیں۔ یعنی ہم رزلٹ سیٹ کھولتے ہیں اور وہاں سے ڈیٹا کو آہستہ آہستہ پڑھتے ہیں۔ کیا یہ کام کرے گا؟ کیا یہ یاد سے گر جائے گا؟ کیا آپ تھوڑا سا پڑھیں گے؟ آئیے ڈیٹا بیس پر بھروسہ کریں، آئیے پوسٹگریس پر بھروسہ کریں۔ ہم اسے نہیں مانتے۔ کیا ہم آؤٹ آف میموری سے گر جائیں گے؟ آؤٹ آف میموری کا تجربہ کس نے کیا؟ اس کے بعد کون اسے ٹھیک کرنے میں کامیاب ہوا؟ کسی نے اسے ٹھیک کرنے کا انتظام کیا۔

اگر آپ کے پاس ایک ملین قطاریں ہیں، تو آپ صرف چن کر انتخاب نہیں کر سکتے۔ OFFSET/LIMIT درکار ہے۔ اس اختیار کے لیے کون ہے؟ اور کون آٹوکمیٹ کے ساتھ کھیلنے کے حق میں ہے؟

یہاں، ہمیشہ کی طرح، سب سے زیادہ غیر متوقع آپشن درست نکلا۔ اور اگر آپ اچانک autoCommit کو آف کر دیتے ہیں تو اس سے مدد ملے گی۔ ایسا کیوں ہے؟ سائنس اس بارے میں نہیں جانتی۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

لیکن پہلے سے طے شدہ طور پر، پوسٹگریس ڈیٹا بیس سے جڑنے والے تمام کلائنٹ پورا ڈیٹا حاصل کرتے ہیں۔ PgJDBC اس سلسلے میں کوئی استثنا نہیں ہے؛ یہ تمام قطاروں کو منتخب کرتا ہے۔

FetchSize تھیم میں ایک تبدیلی ہے، یعنی آپ ایک الگ بیان کی سطح پر کہہ سکتے ہیں کہ یہاں، براہ کرم 10، 50 تک ڈیٹا منتخب کریں۔ لیکن یہ تب تک کام نہیں کرتا جب تک آپ آٹوکومٹ کو بند نہیں کر دیتے۔ آٹوکمیٹ کو آف کر دیا - یہ کام کرنا شروع کر دیتا ہے۔

لیکن کوڈ سے گزرنا اور سیٹ فیچسائز کو ہر جگہ سیٹ کرنا تکلیف دہ ہے۔ لہذا، ہم نے ایک ترتیب بنائی ہے جو پورے کنکشن کے لیے ڈیفالٹ ویلیو کہے گی۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

ہم نے یہی کہا۔ پیرامیٹر ترتیب دیا گیا ہے۔ اور ہمیں کیا ملا؟ اگر ہم چھوٹی مقداریں منتخب کرتے ہیں، مثال کے طور پر، ہم ایک وقت میں 10 قطاریں منتخب کرتے ہیں، تو ہمارے اوپر بہت زیادہ اخراجات ہوتے ہیں۔ اس لیے اس قدر کو تقریباً ایک سو پر مقرر کیا جانا چاہیے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

مثالی طور پر، یقیناً، آپ کو ابھی بھی اسے بائٹس میں محدود کرنے کا طریقہ سیکھنا ہے، لیکن نسخہ یہ ہے: ڈیفالٹ رو فیچ سائز کو ایک سو سے زیادہ پر سیٹ کریں اور خوش رہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آئیے ڈیٹا داخل کرنے کی طرف بڑھتے ہیں۔ اندراج آسان ہے، مختلف اختیارات ہیں۔ مثال کے طور پر، INSERT، VALUES۔ یہ ایک اچھا آپشن ہے۔ آپ کہہ سکتے ہیں "انسرٹ سلیکٹ"۔ عملی طور پر یہ ایک ہی چیز ہے۔ کارکردگی میں کوئی فرق نہیں ہے۔

کتابیں کہتی ہیں کہ آپ کو بیچ اسٹیٹمنٹ پر عمل درآمد کرنے کی ضرورت ہے، کتابیں کہتی ہیں کہ آپ کئی قوسین کے ساتھ زیادہ پیچیدہ کمانڈز کو انجام دے سکتے ہیں۔ اور پوسٹگریس میں ایک شاندار خصوصیت ہے - آپ کاپی کر سکتے ہیں، یعنی اسے تیزی سے کر سکتے ہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اگر آپ اس کی پیمائش کرتے ہیں، تو آپ دوبارہ کچھ دلچسپ دریافتیں کر سکتے ہیں۔ ہم یہ کیسے کام کرنا چاہتے ہیں؟ ہم غیر ضروری احکامات کو پارس نہیں کرنا چاہتے ہیں اور ان پر عمل نہیں کرنا چاہتے ہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

عملی طور پر، TCP ہمیں ایسا کرنے کی اجازت نہیں دیتا۔ اگر کلائنٹ ایک درخواست بھیجنے میں مصروف ہے، تو ڈیٹا بیس ہمیں جوابات بھیجنے کی کوششوں میں درخواستوں کو نہیں پڑھتا ہے۔ حتمی نتیجہ یہ ہے کہ کلائنٹ درخواست کو پڑھنے کے لیے ڈیٹا بیس کا انتظار کرتا ہے، اور ڈیٹا بیس کلائنٹ کے جواب کو پڑھنے کا انتظار کرتا ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اور اس لیے کلائنٹ کو وقتاً فوقتاً ایک مطابقت پذیری پیکٹ بھیجنے پر مجبور کیا جاتا ہے۔ اضافی نیٹ ورک تعاملات، وقت کا اضافی ضیاع۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوفاور جتنا ہم ان کو شامل کریں گے، اتنا ہی برا ہوتا جائے گا۔ ڈرائیور کافی مایوسی کا شکار ہے اور لائنوں کے سائز وغیرہ کے لحاظ سے ہر 200 لائنوں میں تقریباً ایک بار انہیں شامل کرتا ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

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

ایسا ہوتا ہے کہ آپ صرف ایک لائن کو درست کریں اور ہر چیز 10 گنا تیز ہوجائے گی۔ یہ ہوتا ہے. کیوں؟ ہمیشہ کی طرح، اس طرح کا مستقل پہلے ہی کہیں استعمال ہو چکا ہے۔ اور قدر "128" کا مطلب بیچنگ استعمال نہیں کرنا تھا۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

جاوا مائیکرو بینچ مارک ہارنس

یہ اچھی بات ہے کہ اسے سرکاری ورژن میں شامل نہیں کیا گیا تھا۔ ریلیز شروع ہونے سے پہلے دریافت ہوا۔ میں جو بھی معنی دیتا ہوں وہ جدید ورژن پر مبنی ہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آئیے اسے آزماتے ہیں۔ ہم InsertBatch سادہ کی پیمائش کرتے ہیں۔ ہم InsertBatch کی متعدد بار پیمائش کرتے ہیں، یعنی ایک ہی چیز، لیکن بہت سی قدریں ہیں۔ مشکل حرکت۔ ہر کوئی ایسا نہیں کر سکتا، لیکن یہ اتنا آسان اقدام ہے، کاپی کرنے سے کہیں زیادہ آسان۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آپ کاپی کر سکتے ہیں۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

اور آپ یہ ڈھانچے پر کر سکتے ہیں۔ صارف کی ڈیفالٹ قسم کا اعلان کریں، سرنی پاس کریں اور براہ راست ٹیبل پر داخل کریں۔

اگر آپ لنک کھولتے ہیں: pgjdbc/ubenchmsrk/InsertBatch.java، تو یہ کوڈ GitHub پر ہے۔ آپ خاص طور پر دیکھ سکتے ہیں کہ وہاں کیا درخواستیں تیار ہوتی ہیں۔ اس سے کوئی فرق نہیں پڑتا۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

ہم نے لانچ کیا۔ اور پہلی چیز جو ہم نے محسوس کی وہ یہ تھی کہ بیچ کا استعمال نہ کرنا محض ناممکن ہے۔ بیچنگ کے تمام آپشنز صفر ہیں، یعنی عمل درآمد کا وقت ایک بار کے عمل کے مقابلے میں عملی طور پر صفر ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

ہم ڈیٹا داخل کرتے ہیں۔ یہ ایک بہت سادہ میز ہے۔ تین کالم۔ اور ہم یہاں کیا دیکھتے ہیں؟ ہم دیکھتے ہیں کہ یہ تینوں اختیارات تقریباً موازنہ ہیں۔ اور COPY یقیناً بہتر ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

یہ تب ہوتا ہے جب ہم ٹکڑے ڈالتے ہیں۔ جب ہم نے کہا کہ ایک VALUES ویلیو، دو VALUES ویلیوز، تین VALUES ویلیوز، یا ہم نے ان میں سے 10 کو کوما سے الگ کرنے کا اشارہ کیا۔ یہ اب صرف افقی ہے۔ 1، 2، 4، 128۔ یہ دیکھا جا سکتا ہے کہ بیچ داخل، جو نیلے رنگ میں تیار کیا گیا ہے، اسے بہت بہتر محسوس کرتا ہے۔ یعنی، جب آپ ایک وقت میں ایک داخل کرتے ہیں یا اس وقت بھی جب آپ ایک وقت میں چار داخل کرتے ہیں، تو یہ دوگنا اچھا ہو جاتا ہے، صرف اس لیے کہ ہم نے قدروں میں تھوڑا سا زیادہ گھس لیا ہے۔ کم EXECUTE آپریشنز۔

چھوٹی جلدوں پر کاپی کا استعمال انتہائی ناگوار ہے۔ میں نے پہلے دو کو بھی نہیں کھینچا۔ وہ جنت میں جاتے ہیں، یعنی COPY کے لیے یہ سبز نمبر۔

جب آپ کے پاس ڈیٹا کی کم از کم سو قطاریں ہوں تو کاپی کا استعمال کیا جانا چاہیے۔ اس کنکشن کو کھولنے کا اوور ہیڈ بڑا ہے۔ اور، سچ پوچھیں تو، میں نے اس سمت میں کھود نہیں کی۔ میں نے بیچ کو بہتر بنایا، لیکن کاپی نہیں۔

ہم آگے کیا کریں؟ ہم نے اسے آزمایا۔ ہم سمجھتے ہیں کہ ہمیں یا تو ڈھانچے یا ایک ہوشیار بیکتھ استعمال کرنے کی ضرورت ہے جو کئی معنی کو یکجا کرتی ہے۔

PostgreSQL اور JDBC تمام رس کو نچوڑ لیتے ہیں۔ ولادیمیر سیٹنکوف

آج کی رپورٹ سے آپ کو کیا لینا چاہیے؟

  • PreparedStatement ہمارا سب کچھ ہے۔ یہ پیداوری کے لیے بہت کچھ دیتا ہے۔ یہ مرہم میں ایک بڑا فلاپ پیدا کرتا ہے۔
  • اور آپ کو 6 بار EXPLAIN ANALYZE کرنے کی ضرورت ہے۔
  • اور ہمیں اپنے مشکل سوالات کے بقیہ فیصد کو درست کرنے کے لیے OFFSET 0، اور +0 جیسی چالوں کو کم کرنے کی ضرورت ہے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں