پرش به محتوای اصلی

قلع: جستجوی متن کامل برای Postgres

هکرنیوز۱۴۰۵ شهریور ۲۸, شنبه، ساعت ۱۷:۲۲حدود 15 دقیقه مطالعه

آدرس مقاله: https://planetscale.com/blog/introducing-tin آدرس نظرات: https://news.ycombinator.com/item?id=49766611 امتیاز: 201 # نظرات: 75

اریک ریج، پاتریک رینولدز | 16 سپتامبر 2026

یکی از ویژگی های Postgres که مشتریان ما بیشترین درخواست را از ما دارند، جستجوی تمام متن است. امروز، ما مشتاقیم که TIN را معرفی کنیم: یک پسوند جستجوی متن کامل سریع، با ویژگی‌ها، قابل اعتماد برای Postgres. TIN مخفف "Text INdex" است و این همان کاری است که انجام می دهد.

TIN بلافاصله به عنوان نسخه GA برای همه پایگاه های داده Postgres و Neki در دسترس است. آن را بررسی کنید:

ما TIN را ساختیم زیرا معتقدیم یک نمایه متن خوب باید پشتیبانی کند:

یک نمایه متن خوب در Postgres باید از همه این موارد پشتیبانی کند و در عین حال اتصالات، بندهای پیچیده WHERE در سراسر متن کامل و انواع ستون‌ها، به‌روزرسانی‌های مداوم، تکرار، پشتیبان‌گیری و مشاهده صحیح تراکنش را نیز مدیریت کند.

اگرچه حداقل سه فهرست جستجوی متن موجود برای Postgres در حال حاضر وجود دارد، هیچ یک از آنها همه این شرایط را برآورده نکردند. TIN انجام می دهد. TIN نیز واقعا سریع است.

توسعه دهندگان برنامه از فهرست های متنی برای ایجاد انواع ویژگی های جستجو استفاده می کنند. یک پلتفرم تجارت الکترونیک ممکن است نیاز داشته باشد ده محصول برتر را که شامل همه کلمات کلیدی در جستجو هستند جستجو کند:

ممکن است برای بازگرداندن هر سندی که حاوی یک یا چند مورد از مجموعه ای از کلمات کلیدی است، به یک پلت فرم کشف قانونی نیاز باشد، اما به رتبه بندی اصلا اهمیتی نمی دهد:

یک پلت فرم برچسب گذاری عکس ممکن است تعداد دقیقی از عکس ها را با یک برچسب خاص نشان دهد:

اکثر برنامه‌ها نیاز به درج، به‌روزرسانی و حذف اسناد دارند، حتی در حالی که به جستجوی فهرست ادامه می‌دهند. عبارت‌های جستجو باید به محض اینکه متعهد شدند مطابق با ردیف‌های جدید یا تغییر یافته را برگردانند.

ما معیارهایی را برای ارزیابی عملکرد برای همه موارد استفاده بالا و موارد دیگر اجرا کردیم. بارهای کاری را امتحان کردیم:

ما TIN را با مجموعه‌های متنی مختلف اندازه‌گیری کرده‌ایم: تمام ویکی‌پدیا، مجموعه‌ای از نظرات Reddit که مجموعا 2.3 ترابایت است، و حجم کاری ترکیبی که ما آن را با 797 گیگابایت مقالات تحقیقاتی با دسترسی آزاد، اسناد حقوقی، کتاب‌های حوزه عمومی و ایمیل‌های انرون می‌نامیم. نتایج معیاری که در این مقاله به اشتراک می گذاریم، از صادرات پرسش و پاسخ از Stack Exchange است: مجموعه 85 گیگابایتی با 150 میلیون سند. از آنجایی که پیکره هیچ ردیابی پرس و جوی استانداردی ندارد، ما با نمونه‌برداری از زیررشته‌هایی از 2 تا 15 عبارت، یک نمونه مصنوعی ایجاد کردیم.

ما هر زیررشته را به سه روش تفسیر کردیم: به عنوان یک ربط، به عنوان یک جدایی و به عنوان یک عبارت عبارت، در مجموع 1719 پرس و جو.

ما معیارهای خود را روی یک نمونه AWS i7i.8xlarge EC2 با حافظه داخلی NVMe و یک CPU مدرن و با قابلیت AVX-512 اجرا کردیم. برای هر افزونه جستجوی متن، Postgres 18.6 را در یک محفظه ایزوله محدود به 8 vCPU و 32 گیگابایت رم راه اندازی کردیم. این به اندازه کافی کوچک است تا نشان دهد که هر سیستم ایندکس چگونه عمل می کند، زمانی که شاخص فقط در بافرهای Postgres قرار نمی گیرد. فازهای معیار به صورت متوالی اجرا می شدند، بنابراین موتورها برای منابع رقابت نمی کردند.

ما یک نمونه EC2 مستقل را انتخاب کردیم تا تأثیر سربار عملیاتی و تکرار را به حداقل برسانیم و اطمینان حاصل کنیم که هر کسی که می‌خواهد معیارهای شاخص‌های جستجوی متن رقیب ما را بازتولید کند، می‌تواند این کار را با استفاده از همان نوع نمونه و محدودیت‌های ظرف انجام دهد.

برای هدایت ترافیک جستجو در برابر کانتینرهای Postgres، از معیار ParadeDB استفاده کردیم. ما یک نسخه فورک داریم که قبل از شروع اندازه‌گیری، پیش گرم می‌شود و معیارهایی را برای بایت‌های خوانده شده و بایت‌های WAL نوشته شده اضافه می‌کند. ما همه پارامترهای Postgres را در پیش‌فرض‌هایی که Benchmarker ارائه می‌کند، رها کردیم، به جز سه مورد: max_parallel_workers را به 8 (از 40)، shared_buffers را به 24 گیگابایت (از 128 مگابایت)، و maintenance_work_mem را به 24 گیگابایت (از 64 مگابایت منابع) برای بهترین تطابق با منابع حاوی قرار دادیم.

ما Benchmarker را روی همان نمونه EC2 به عنوان سرور Postgres هدف اجرا کردیم تا اطمینان حاصل کنیم که تأخیر شبکه بر اندازه‌گیری‌ها تأثیر نمی‌گذارد.

برای هر سناریو، ما عملکرد TIN v1.0.2 را در برابر سایر نمایه‌های جستجوی متن Postgres که اصلا قادر به اجرای حجم کار بودند، اندازه‌گیری کردیم: ParadeDB v0.25.2، pg_textsearch v1.4.0، و شاخص GIN ساخته شده در Postgres v18.6. به غیر از TIN، تنها ParadeDB توانست تمام معیارها را تکمیل کند.

ایندکس ها از 33% تا 61% اندازه بدنه متغیر هستند و از 8 تا 129 دقیقه برای آماده سازی، ساخت و نهایی شدن زمان صرف می شوند. سه موتور غیر از TIN با محدودیت 32 گیگابایتی پیکربندی شده کانتینر از کار افتادند، بنابراین فقط برای ساخت های شاخص، رم موجود را همانطور که در جدول نشان داده شده است افزایش دادیم. قبل از اجرای کوئری ها، کانتینر را روی 32 گیگابایت رم برای همه تنظیم می کنیم.

اولین معیار ما TIN را با ParadeDB مقایسه می‌کند، برای حجم کاری با پرس و جوهای ترکیبی (ارتباط، تفکیک، و عبارت)، 10 نتیجه برتر با امتیاز BM25، بدون نوشتن همزمان در نمایه. TIN 25× به اندازه پرس و جو در ثانیه به اندازه ParadeDB رسیدگی می کند، با تأخیر p99 26× کمتر. GIN نمی‌تواند این معیار را تکمیل کند، زیرا با انجام جستجوهای تفکیک، حافظه آن تمام می‌شود. pg_textsearch نمی تواند معیار را تکمیل کند زیرا فقط جستجوهای جدایی را انجام می دهد.

معیار بعدی ما TIN را با ParadeDB و Postgres GIN، برای 10 جستجوی ربط و عبارت برتر، بدون نوشتن همزمان، مقایسه می‌کند. TIN و ParadeDB با استفاده از BM25 رتبه بندی می شوند، در حالی که GIN با استفاده از ts_rank_cd رتبه بندی می شوند. TIN 10× به اندازه ParadeDB و 541× به اندازه GIN، با تأخیر p99 به ترتیب 6× و 1356× کمتر پاسخ می دهد. pg_textsearch دوباره وجود ندارد زیرا فقط پرس و جوهای جدایی را مدیریت می کند.

نتیجه سوم ما TIN را با ParadeDB و pg_textsearch مقایسه می‌کند، برای حجم کاری با جستارهای جداسازی، 10 نتیجه برتر با امتیاز BM25، و مشتری همزمان با هدف قرار دادن 1000 درخواست UPDATE در ثانیه. TIN 36× به اندازه pg_textsearch و 57× پرس و جو به اندازه ParadeDB، با تأخیر p99 به ترتیب 24× و 36× کمتر پاسخ می دهد. در طول ده دقیقه، TIN 270279 بروزرسانی را تکمیل می کند، در حالی که ParadeDB 185584 را تکمیل می کند و pg_textsearch تنها 735 را تکمیل می کند.

رویکرد ParadeDB برای پذیرش نوشته‌ها، توان خواندن و تأخیر را قربانی می‌کند. pg_textsearch همان QPS 3.5 را برای خوانندگان با و بدون نوشتن حفظ می کند زیرا ترافیک خواندن مداوم مانع از دریافت قفل های مورد نیاز ترافیک نوشتن می شود، بنابراین نوشتن پس از چند ثانیه متوقف می شود. GIN دوباره وجود ندارد زیرا حافظه آن در جستارهای جداسازی تمام می شود.

در مقدمه، ما ادعا کردیم که TIN بسیار سریع است.

نمودار نهایی ما نشان می‌دهد که TIN، ParadeDB و Postgres GIN چه کاری می‌توانند انجام دهند زمانی که ایندکس به طور کامل در بافرهای مشترک قرار می‌گیرد. این حجم کاری اسنادی را که با یک جستجوی تفکیک با ویکی‌پدیا، یک مجموعه 8.0 گیگابایتی مطابقت دارند، حساب می‌کند (اما رتبه‌بندی نمی‌کند). pg_textsearch در اینجا وجود ندارد زیرا فقط می تواند پرس و جوهای top-k را انجام دهد، بدون شمارش پرس و جوها.

شاید این نمودار کافی باشد، اما همه موارد استفاده ما را پوشش نمی دهد. در اینجا همان سناریوها، به علاوه چندین مورد دیگر، به شکل جدول آمده است. ستون "MB/query" نشان می‌دهد که هر فهرست چه مقدار داده را از دیسک یا حافظه پنهان بلوک برای هر پرس و جو می‌خواند. اعداد کمتر TIN برای MB/query بخشی از علت سریعتر بودن آن است، و همچنین تأثیر پرس‌وجوهای TIN را بر روی حافظه پنهان بلوک و ظرفیت ورودی/خروجی کاهش می‌دهد، به این معنی که سایر پرس‌وجوها در همان سرور نیز سریع می‌مانند.

همانطور که می بینید، در طیف گسترده ای از سناریوها، TIN حداقل 8× بالاتر از گزینه های دیگر توان عملیاتی دارد، داده های بسیار کمتری را از روی دیسک می خواند، و حتی زمانی که شاخص صدها ردیف در ثانیه به روز می شود، تنها یک افت عملکرد کوچک را تجربه می کند.

باور عملکرد TIN در معیارها ممکن است سخت باشد. به امید اینکه بتوانیم آن را باورپذیرتر کنیم، یا حداقل کنجکاوی خواننده را ارضا کنیم، کمی در مورد انتخاب های معماری که TIN را بسیار سریع می کنند توضیح خواهیم داد. به طور خلاصه: همه ارسال‌های اسناد به جای شناسه‌های اسناد پیوسته، Postgres ctid هستند، و این خود به عملیات‌های تقاطع و اتحاد بسیار بردار در CPUهای مدرن کمک می‌کند.

یک نمایه متنی برای هر نسخه از هر سندی که ایندکس می کند به یک شناسه نیاز دارد. این شناسه‌ها را در فهرست‌های پست‌های بسیار فشرده گروه‌بندی می‌کند. هر فهرست پست ها تمام اسنادی را که حاوی یک کلمه معین هستند را دنبال می کند. در یک مجموعه بزرگ، یک لیست پست برای یک کلمه معمولی مانند "the" ممکن است حاوی میلیاردها پست باشد، در حالی که لیست پست‌ها برای اصطلاحی مانند "xyz-9876" فقط شامل تعداد کمی است.

اکثر سیستم های جستجوی متن فهرست های خود را به بخش هایی سازماندهی می کنند. به n سندی که پست آنها در یک بخش وجود دارد معمولا شناسه های سند 1 تا n اختصاص داده می شود. شناسه‌های اسناد متوالی به فهرست‌های پست‌ها اجازه می‌دهند تا با استفاده از تکنیک‌های مختلف مانند رمزگذاری دلتا و بسته‌بندی بیت، به شدت فشرده شوند. اما همچنین به این معنی است که شناسه های اسناد در بخش های مختلف به طور مستقل اختصاص داده می شوند. شناسه سند 42 در بخش 4 یک سند کاملا متفاوت با شناسه 42 در بخش 7 است.

TIN همچنین فهرست خود را به بخش ها سازماندهی می کند، اما نه برای اهداف شماره گذاری اسناد. در عوض، TIN مستقیما از مقدار ctid Postgres به عنوان شناسه سند استفاده می کند.

هر نسخه از هر ردیف (تعدادی) ذخیره شده در جدول Postgres دارای یک مقدار ctid مرتبط است. ctid مخفف کلمه "current tuple identifier" است. هر ردیفی که درج یا به‌روزرسانی شود یک ctid جدید دریافت می‌کند. این یک عدد 48 بیتی است که مستقیما مکان فیزیکی یک تاپل را در پشته Postgres مشخص می کند. به صورت متنی به صورت (<block number>, <offset number>) نمایش داده می شود، 32 بیت بالا نشان دهنده شماره بلوک و 16 بیت پایین نشان دهنده افست در آن بلوک است. از این پس به قسمت <block number> به عنوان «شماره صفحه» یا «صفحه» اشاره می کنیم.

با توجه به ctid از (190، 17) ما می دانیم که تاپلی که آن را نشان می دهد، در شکاف هفدهم در صفحه 190 است. جستجوی فوری O(1)! حتی می توانید مستقیما با استفاده از ctid s ردیف ها را از پشته پرس و جو کنید و بازیابی کنید:

TIN مستقیما از ctid s استفاده می کند زیرا Postgres به صورت داخلی از ctid s استفاده می کند. پسوندهای Postgres که نوع شاخص جدیدی را پیاده سازی می کنند باید ctid s را برگردانند. اسکن‌های بیت‌مپ Postgres توسط بیت مپ‌های بالقوه با اتلاف ctid s پشتیبانی می‌شوند. انواع نمایه داخلی Postgres (b-tree، GIN، GiST و هش) از ctid به عنوان پست خود استفاده می کنند. ctid ها همه جا در Postgres هستند.

برای کار در Postgres، یک سیستم جستجوی متنی که شناسه‌های متوالی را اختصاص می‌دهد، باید آن شناسه‌ها را دوباره به یک ctid تبدیل کند تا Postgres با آن کار کند. هر دو ParadeDB و pg_textsearch یک ساختار داده جداگانه را فقط برای انجام این نقشه برداری حفظ می کنند. اگر یک جستجوی متنی با 10 میلیون ردیف مطابقت داشته باشد، ParadeDB و pg_textsearch باید 10 میلیون شناسه را در نگاشتهای ctid خود جستجو کنند. TIN به طور کامل از این کار جلوگیری می کند.

تکنیک‌های فشرده‌سازی فهرست پست‌های معمولی با اعداد 48 بیتی ناپیوسته به خوبی کار نمی‌کنند. کدگذاری دلتا در هر مرز صفحه شکسته می‌شود و بیت مپ‌ها برای کارآمدی بسیار کم هستند. خوشبختانه، برخی از ویژگی های جالب صفحات Postgres رمزگذاری بیت مپ دو سطحی را کاربردی می کند. یک صفحه 8 کیلوبایتی هرگز نمی‌تواند بیش از 291 تاپل داشته باشد (8192 بایت، منهای 24 برای سرصفحه صفحه، تقسیم بر حداقل 28 در هر تاپل غیر خالی)، و برای طرح‌واره‌های جدول با TEXT و ستون‌های دیگر، صفحات اغلب حاوی 32 یا کمتر تاپل هستند.

بنابراین فهرست شماره صفحات به اندازه کافی متراکم است که بتوان از یک بیت مپ استفاده کرد، و در داخل هر صفحه، فهرست اعداد افست به اندازه کافی متراکم (و به اندازه کافی کوچک) برای استفاده از بیت مپ های کوچک در هر صفحه است.

صرفه جویی نسبت به ذخیره ساده مقادیر ctid 48 بیتی می تواند بسیار قابل توجه باشد. در کل مجموعه، عبارات با فرکانس بالا به 1 بیت در هر پست نزدیک می شوند، اصطلاحات فرکانس متوسط ​​حدود 7 بیت در هر پست قرار می گیرند، و اصطلاحات با بسامد نادر می توانند به 25 بیت در هر پست نزدیک شوند. اصطلاحاتی که فقط یک بار ظاهر می شوند به هیچ وجه به عنوان بیت مپ ذخیره نمی شوند.

بیت مپ های سطح صفحه TIN (که صفحات حاوی عبارت مشخصی هستند) دارای 256 بیت هستند که به خوبی در ثبات های برداری در هر پردازنده x86 با AVX2 یا بالاتر قرار می گیرد. که چندین بهینه سازی را امکان پذیر می کند.

پرس و جو را کلمه کمیاب AND در نظر بگیرید. TIN AND نقشه های بیتی سطح صفحه، 256 بیت (صفحه) در یک زمان است. هر بیتی که در تقاطع وجود ندارد، صفحه ای است که TIN بیت مپ های سطح افست آن اصلا نیازی به رمزگشایی ندارد.

برای COUNT(*) پرس و جوهای تفکیک مانند OR rareword، TIN اغلب از خواندن لیست پست ها به طور کامل صرف نظر می کند. فراداده شاخص TIN تعداد دقیق پست های هر اصطلاح را ذخیره می کند. اگر بیت مپ های سطح صفحه برای دو کلمه هیچ بیت مشترکی نداشته باشند، شمارش تفکیک آنها فقط مجموع آن تعداد دقیق ارسال است.

هر بیت مپ سطح صفحه در یک ثبات AVX2 و هر بیت مپ سطح افست در یک ثبات AVX-512 یا دو رجیستر AVX2 قرار می گیرد. پرس و جوهای پیوند و تفکیک به ترتیب فقط دستورالعمل های AND و OR در آن ثبات های برداری هستند. کوئری هایی که تعداد تطابق ها را شمارش می کنند می توانند از دستورالعمل های POPCNT بومی CPU برای شمارش بیت ها در bitmap به دست آمده استفاده کنند. حلقه های گران قیمت و دستورالعمل های شاخه تا حد زیادی قابل اجتناب هستند.

پرس و جوی که به جای شمارش، سطر می خواهد، ctid را از موقعیت بیت محاسبه می کند تا اینکه آن را روی دیسک جستجو کند. موقعیت یک بیت مجموعه ctid است.

سند نشان می‌دهد که TIN از یک بخش معین به Postgres برمی‌گرداند، به طور طبیعی صفحات را شناسایی می‌کند، و در یک صفحه، به ترتیب پشته‌ها تاپله می‌شود. این به این معنی است که وقتی Postgres نیاز به خواندن تاپل های منطبق از پشته دارد، به ترتیب پشته اتفاق می افتد. حتی با دیسک های مدرن NVMe، دسترسی متوالی بسیار سریعتر از دسترسی تصادفی است. TIN این بهینه سازی را به صورت رایگان دریافت می کند.

TIN نتایجی را برمی‌گرداند که MVCC-correct هستند، به این معنی که دستوری که در هر نقطه از زمان اجرا می‌شود فقط تاپل‌هایی را می‌بیند یا عمل می‌کند که در حال حاضر برای آن قابل مشاهده هستند. این بدان معنی است که هر نتیجه پرس و جوی پشتیبان پشته باید برای مشاهده نسبت به عکس فوری فعلی بررسی شود.

چند رویکرد متفاوت در این مورد وجود دارد. برخی از پرس و جوها ذاتا به صورت پشته بررسی می شوند:

از آنجایی که پرس و جو داده های پشته واقعی (ستون های a، b، c) را برمی گرداند، TIN باید تمام ctid های منطبق برگردانده شده توسط ==> 'give you up' را از پشته دریافت کند. وقتی TIN از Postgres داده های فیزیکی تاپل پشت هر ctid را می خواهد، Postgres به TIN می گوید که آیا آن تاپل برای عکس فوری فعلی قابل مشاهده است یا خیر. اگر چنین باشد، TIN آن را برمی گرداند. در غیر این صورت، TIN به ctid منطبق بعدی منتقل می شود، تا زمانی که همه موارد قابل مشاهده برگردانده شوند.

سایر اشکال پرس و جو را می توان به طور مشابه "Index Only Scan" Postgres اجرا کرد که در آن پاسخ مستقیما از نمایه بدون لمس پشته (یا حداقل امیدواریم که نه همه پشته) برگردانده می شود. یک پرس و جو فقط شمارش مانند این را در نظر بگیرید:

اگر هر صفحه پشته به صورت کاملا قابل مشاهده علامت‌گذاری شود، TIN می‌تواند آن تعداد را بدون لمس یک صفحه پشته برگرداند.

البته همه داده‌ها ثابت نیستند، و در مورد پشته‌های جهش‌یافته، TIN بهینه‌سازی‌های بیشتری انجام می‌دهد تا اطمینان حاصل کند که تنها با انجام تقاطع‌های مستقیم با نقشه دید Postgres، ردیف‌های قابل مشاهده را شمارش می‌کند. نقشه‌های بیتی سطح صفحه TIN دقیقا مکانیسم مناسبی برای تلاقی مؤثر در برابر نقشه‌های دید Postgres هستند که همچنین نقشه‌های بیتی سطح صفحه هستند. فقط ctid ها در صفحاتی که همه قابل مشاهده نیستند باید در مقابل پشته بررسی شوند. به طور معمول، یک نمایه Postgres تمام ctidهایی را که با هم مطابقت دارند را بدون در نظر گرفتن قابلیت مشاهده برمی گرداند، و مجری Postgres قابلیت مشاهده هر یک را بررسی می کند.

TIN اسکن‌های سفارشی را برنامه‌ریزی می‌کند که بررسی‌های دید را به خود TIN منتقل می‌کند، جایی که می‌توانند از دستورالعمل‌های برداری در نقشه‌های بیتی سطح صفحه استفاده کنند.

فهرست‌های متنی که از حذف اسناد پشتیبانی می‌کنند، معمولا نوعی فهرست «سنگ قبر» را نگه می‌دارند که با موتور آنها مناسب است. TIN تفاوتی ندارد. TIN یک بیت مپ زنده بودن هر بخش، یک بیت در هر ctid را نگه می‌دارد، به همان روشی که نقشه‌های بیتی سطح صفحه و افست کار می‌کنند، سازماندهی شده است. هنگامی که VACUUM اجرا می شود و مشخص می کند که یک ctid از پشته حذف شده است (در نتیجه به روز رسانی یا DELETE)، TIN بیت زنده آن ctid را پاک می کند.

گروه‌هایی از صفحات با حداقل یک بیت پاک‌شده علامت‌گذاری می‌شوند، و زمانی که یک پرس‌وجو یک گروه صفحه علامت‌گذاری شده را لمس می‌کند، TIN همچنین بیت‌مپ‌های افست فهرست پست‌ها را در برابر بیت مپ زنده نشان می‌دهد، بنابراین هرگز یک تاپلی را که واقعا حذف شده است برنمی‌گرداند یا شمارش نمی‌کند.

هنگامی که برای اولین بار یک شاخص جدید برای یک جدول ایجاد می کند، TIN n بخش غیرقابل تغییر ایجاد می کند که هر کدام حاوی پست هایی برای 1/n از صفحات مرتبط با آن جدول در پشته است. با تغییر داده‌ها، TIN بخش‌های قابل تغییر ایجاد می‌کند که برای جستجو کارایی کمتری دارند، اما امکان درج آسان اسناد جدید را فراهم می‌کنند. در نهایت، یک کارگر پس‌زمینه، هر بخش قابل تغییر را به یک بخش تغییرناپذیر ارتقا می‌دهد: بدون تغییر، اما برای جستجو بسیار کارآمدتر.

پس از مدتی، TIN شروع به ادغام بخش های تغییرناپذیر به بخش های تغییرناپذیر بزرگتر می کند. این در پس زمینه نیز اتفاق می افتد.

سیستم‌های نمایه‌سازی متنی که از شناسه‌های اسناد متوالی استفاده می‌کنند، هنگام ایجاد یک بخش جدید و ادغام‌شده، ملزم به شماره‌گذاری مجدد همه اسناد هستند. همانطور که در بالا ذکر شد، شناسه سند 42 در بخش 4 با ID 42 در بخش 7 یکسان نیست. بنابراین وقتی بخش های 4 و 7 ادغام می شوند، باید یک شماره گذاری جدید برای مجموعه ترکیبی اسناد اعمال شود و کل داده های هر بخش دوباره بسته بندی، فشرده سازی و بازنویسی می شود. در حالی که فضای ذخیره سازی برای ادغام دو بخش کاملا 2× نیست، می تواند نزدیک باشد.

TIN نه از مشکل شماره گذاری مجدد رنج می برد و نه از اثرات تقویت نوشتن پایین دست آن.

از آنجا که TIN از مقادیر ctid Postgres به عنوان شناسه سند خود استفاده می کند، چیزی برای شماره گذاری مجدد وجود ندارد. یک پست مانند (190، 17) در هر بخش معنای یکسانی دارد. بیت مپ های سطح صفحه و سطح افست در هر بخش معنای یکسانی دارند. هنگامی که TIN بخش‌ها را ادغام می‌کند، بسیاری از بیت‌مپ‌ها از هر بخش قدیمی می‌توانند دست نخورده در بخش جدید دوباره استفاده شوند. آنها مجبور نیستند دوباره فشرده شوند یا حتی کپی شوند. TIN به سادگی می تواند مالکیت بیت مپ های ذخیره شده روی دیسک را از بخش های قدیمی به بخش جدید منتقل کند.

این امر تقویت نوشتن را کاهش می دهد و در بیشتر هزینه های CPU و I/O که معمولا با ادغام بخش ها مرتبط است، صرفه جویی می کند.

بنابراین به همین دلیل است که TIN در هر معیار حداقل 8× سریعتر است: اثرات پایین دستی انتخاب ctid به عنوان قالب اصلی برای هر پست در فهرست.

اگر می‌خواهید ببینید TIN روی داده‌های نوشتاری شما چقدر سریع است، درباره ویژگی‌ها بیشتر بخوانید یا مستقیما به راهنمای شروع بروید. مشتاقانه منتظریم ببینیم با آن چه می سازید.

خواندن متن کامل در هکرنیوزبه زبان اصلی، در سایت ناشر باز می‌شود
متن اصلی (انگلیسی)

Tin: full-text search for Postgres

Article URL: https://planetscale.com/blog/introducing-tin Comments URL: https://news.ycombinator.com/item?id=49766611 Points: 201 # Comments: 75

همه‌ی اخبار فناوری