یک پرسوجوی بازگشتی که در نسخه ۱.۵ نزدیک به ۵ ثانیه زمان میبرد، اکنون در ۰.۱۲ ثانیه به پایان میرسد. DuckDB با انتشار نسخه ۲.۰ (با نام رمز Cyanoptera)، کفِ عملکرد پایگاهدادههای تحلیلی را جابهجا کرده است. نام این نسخه از «مرغابی تیل دارچینی» (Anas cyanoptera)، پرندهای قهوهای-قرمز در آمریکای غربی گرفته شده است. این نسخه که در پاییز امسال عرضه میشود، حاصل بیش از ۱۰ هزار کامیت از زمان انتشار نسخه ۱.۵ در ماه مارس است.
برای سالها، داکدیبی صرفاً به عنوان یک پایگاهداده در-فرآیند (in-process) عمل میکرد؛ یعنی دقیقاً داخل همان برنامهای زندگی میکرد که از آن استفاده میکرد. این ساختار برای تحلیلهای محلی فوقالعاده سریع بود، اما استفاده از آن را در استقرارهای طولانیمدت و چند-مستأجری (multi-tenant) محدود میکرد. به نقل از پیشنمایش سایت duckdb.org، تیم توسعه با معرفی معماری بومی کلاینت/سرور، این محدودیت را از بین برده است و این آغاز «سالِ داکدیبی به عنوان یک سرور» است.
تصور کنید موتور تحلیلی شما دیگر فقط روی لپتاپتان نیست، بلکه به عنوان یک مرکز متمرکز برای کل خط لوله دادههای شما عمل میکند. این تغییر اجازه میدهد داکدیبی در حجمهای کاری خاص، مستقیماً با پایگاهدادههای عمومی مثل PostgreSQL رقابت کند و در عین حال لبهی تحلیلی خود را حفظ نماید. از آنجایی که داکدیبی از روز اول به عنوان یک پایگاهداده تراکنشی با پشتیبانی از اتصالات متعدد، MVCC کامل و جداسازی تراکنشها ساخته شده بود، بهطور منحصربهفردی برای این انتقال آماده است.
چرخش به سمت حالت سرور
قلب تپنده نسخه ۲.۰، افزونه Quack است. این افزونه یک پروتکل بومی را پیاده میکند که به هر فرآیند داکدیبی اجازه میدهد پایگاهدادهها را روی شبکه سرویسدهی کند. سایر نمونههای داکدیبی میتوانند با استفاده از دستور جدید CONNECT به این سرور متصل شوند. برای مثال، سرور با دستور CALL quack_serve(token = 'my_token') اجرا شده و کلاینت از طریق ATTACH 'quack:server.example.com' AS qk (TOKEN 'my_token'); CONNECT qk; به آن میپیوندد.
این دستور CONNECT جایگزین رسمی راهکارهای موقتی پیشین مانند remote.query($$...$$) است. این دستور طراحی شده تا یک نشست (session) را به هر پایگاهداده راه دور که از این پروتکل پشتیبانی میکند متصل کند و اجازه دهد نتایج به کلاینت استریم شوند در حالی که اجرای واقعی روی سرور رخ میدهد.
این قابلیت فقط محدود به ارتباط بین داکدیبیها نیست. بهینهساز جدید remote pushdown (#22914) به داکدیبی اجازه میدهد SQL را مستقیماً به سرورهای PostgreSQL و MySQL بفرستد. به جای کشیدن جداول عظیم روی شبکه، پردازش در محل استقرار دادهها انجام شده و فقط نتایج بازگردانده میشوند. کاربران میتوانند بهسادگی دستور CONNECT 'postgres://localhost/mydb'; را اجرا کنند تا پرسوجوها مستقیماً روی سرور پستگرس اجرا شوند.
برای پشتیبانی از این مدل استقرار طولانیمدت، لایه متریکهای بازطراحیشده (#22799) قابلیت مشاهده و ثبت وقایع (logging) لازم برای نظارت بر سرور در محیط عملیاتی را فراهم میکند. این لایه به مدیران اجازه میدهد دقیقاً ببینند یک نمونه داکدیبی در لحظه چه کاری انجام میدهد. تیم توسعه اشاره کرد که اشتیاق جامعه برای این قابلیت چنان زیاد بود که کلاینتهای مستقل برای پروتکل Quack تنها چند هفته پس از پیشنمایش ساخته شدند.
مدیریت دادهها و نوع VARIANT
دادههای نیمهساختاریافته معمولاً سرعت پرسوجوهای تحلیلی را کاهش میدهند. نسخه ۲.۰ نوع داده VARIANT را به یک شهروند درجهیک تبدیل کرده است. این نوع داده را شبیه به JSON اما با قدرت بسیار بیشتر تصور کنید؛ دادههایی با ساختارهای متفاوت را در هر ردیف ذخیره میکند اما بهطور خودکار ساختار را برای اجرای سریع و فشردهسازی بالا «خرد» (shred) میکند، بدون اینکه نیاز به تعریف طرح (schema) باشد. این ویژگی آن را برای جذب لاگهای بلادرنگ که در آن رکوردهای JSON-مانند در طول زمان تکامل مییابند، ایدهآل میکند.
در نسخه ۲.۰، این خط لوله بهصورت سرتاسری (end-to-end) پیاده شده و شامل موارد زیر است:
- اجرای خردشده: اجرای مستقیم از روی حافظه ذخیرهسازی (#20912).
- Pushdown استخراج: انتقال فیلترها به مرحله اسکن (#22478).
- یکپارچگی با Parquet: خواندن و نوشتن VARIANT خردشده برای فایلهای Parquet.
- توابع جدید: خانواده توابع
variant_*شاملvariant_type()،variant_keys()وvariant_contains().
برای مثال، کاربر اکنون میتواند دستور SELECT * FROM events WHERE variant_contains(payload, {'user': {'id': 42}}::VARIANT); را اجرا کند تا دادههای نیمهساختاریافته را با کارایی بالا جستوجو کند. تیم توسعه قصد دارد در نهایت نوع داده استاندارد JSON را با VARIANT پشتیبانی کند تا تمام بارهای کاری موجود JSON بدون نیاز به تغییر در پرسوجوها، بهطور خودکار شتاب بگیرند.
تریگرها و خودکارسازی
داکدیبی v2.0 اکنون از تریگرها (Triggers) بهطور کامل پشتیبانی میکند که یکی از درخواستهای قدیمی جامعه کاربران بود. این قابلیت برای سرویسهای طولانیمدت و ویژگیهای داخلی موتور حیاتی است و شامل موارد زیر میشود:
- زمانبندی و دامنه: پشتیبانی از تریگرهای
BEFOREوAFTERو همچنین تریگرهای «برای هر ردیف» (FOR EACH ROW) یا «برای هر دستور» (FOR EACH STATEMENT). - جداول انتقال: استفاده از
REFERENCING OLD TABLEوNEW TABLEبرای ردیابی تغییرات. - مدیریت: پشتیبانی از چندین تریگر برای هر رویداد، استفاده از
RETURNINGدر جداول تریگر شده و دستورDROP TRIGGER.
یک مورد استفاده کلاسیک، ایجاد جداول حسابرسی (audit tables) است. با یک تریگر، سامانه میتواند بهطور خودکار تغییرات یک جدول هدف را در هنگام رویداد UPDATE از طریق پیوند دادن جداول انتقال قدیمی و جدید در جدول حسابرسی ثبت کند. برای مثال: CREATE TRIGGER trg_audit AFTER UPDATE ON target REFERENCING OLD TABLE AS o NEW TABLE AS n FOR EACH STATEMENT INSERT INTO audit SELECT n.id, o.val, n.val FROM o JOIN n ON o.id = n.id;.
قابلیتهای پیشرفته SQL
داکدیبی در حال گسترش تهاجمی دیالکت SQL خود برای مدیریت بارهای کاری مدرن AI و دادههای پیچیده است. اضافات کلیدی عبارتند از:
- اتصالهای NEAREST: یک عبارت اتصال جدید (#24137) برای جستوجوی شباهت top-k، که مخصوص بارهای کاری بردار معنایی (Embedding) با استفاده از توابعی مثل
array_cosine_similarityطراحی شده است. یک پرسوجوی نمونه:SELECT q.user_id, t.product_id FROM users q INNER JOIN products t APPROX NEAREST 2 BY SIMILARITY array_cosine_similarity(q.embedding, t.embedding);. - DML در CTEها: پشتیبانی از
INSERT،UPDATE،DELETEوCOPYبه عنوان مراحل خط لوله در Common Table Expressions (#21634, #21997, #24217). این امکان اجازه میدهد الگوهایی مثل حذف از جدول موقت و درج ردیفهای بازگشتی در آرشیو را در یک مرحله انجام داد:WITH moved AS MATERIALIZED ( DELETE FROM staging RETURNING * ) INSERT INTO archive SELECT * FROM moved;. - طرحهای تودرتو: پشتیبانی از طرحها در داخل طرحها (#23492, #24222)، که ساختارهایی مثل
CREATE SCHEMA finance.reportsرا ممکن میکند. - سینتکس متغیرها: جایگزینی تابع طولانی
getvariable()با سینتکس ساده$x(مثلاًWHERE amount > $threshold) (#21194). - تغییرات JSON: توابع جدیدی مثل
json_set،json_insert،json_replaceوjson_remove(#23786) برای اصلاح در جایای اسناد JSON. مثال:SELECT json_set('{"a":1}', '$.b', '2');. - CTEهای بازگشتی: اکنون از تجمیع
USING KEY(#19481) برای الگوریتمهای تکرار شونده در SQL خالص پشتیبانی میکنند. یک پیادهسازی نمونه:WITH RECURSIVE tbl(a, b) USING KEY (a, avg(b)) AS (...). - انطباق با استانداردها: اضافه شدن
FETCH FIRST 2 ROWS ONLY(#23533)، تابعOVERLAY()(#22456) و استفاده ازUNNESTدرGROUP BY(#23644). - معناشناسی Merge: تعریف دقیق معناشناسی برای
MERGEوUPDATE ... FROMدر ردیفهایی که چندین بار مطابقت دارند (#24058).
بازبینی موتور و عملکرد
شگفتانگیزترین بنچمارک در پیشنمایش v2.0، افزایش ۴۰ برابری سرعت در CTEهای بازگشتی است. یک پرسوجوی دسترسی تک-منبع روی گرافی با یک میلیون یال، از ۴.۹۰ ثانیه در نسخه ۱.۵.۴ به تنها ۰.۱۲ ثانیه کاهش یافت.
این جهش مدیون بازنویسی کامل موتور CTE بازگشتی (#22211) است. سایر نقاط قوت عملکردی عبارتند از:
- بهینهسازی تجمیع: تجمیعهای جزئی اکنون به زیرِ اتصالها منتقل میشوند (#22572) و تجمیعهای تکراری مجدداً استفاده میشوند (#24543).
- مدیریت حافظه: تجمیعها اکنون در صورت بزرگتر شدن از حافظه، به دیسک منتقل میشوند (spill to disk) (#24499).
- سرعت CLI: رابط خط فرمان ویندوز در متریالیزه کردن نتایج چند-رشتهای حدود ۲.۲ برابر سریعتر شده است (#24036).
- حذف گروههای ردیف: گسترش گسترده نقشههای منطقه (zone maps) و فیلترهای Bloom در Parquet برای نادیده گرفتن دادههای غیرضروری در structها، لیستها، اعشار، UUIDها و پیشگفتههای توابع (مثلاً
contains(message, 'ERROR')یاsubstr(code, 1, 3) = 'NL-'). - آگاهی از پارتیشن: برنامهریز و بهینهساز اکنون از پارتیشنبندی در فرمتهای Lakehouse مثل DuckLake، Iceberg و Parquetهای پارتیشنبندی شده در S3 بهطور کامل بهره میبرند (#22336)، همراه با بازطراحی نوشتنهای پارتیشنشده (#22225, #22620).
ورودی/خروجی (I/O) ناهمگام نیز یک پیروزی بزرگ برای کاربران ابری است. با جداسازی لایه I/O از پردازش پرسوجو، داکدیبی اکنون میتواند خواندنهای موازی بسیار بیشتری را از S3 و سایر ذخیرهسازهای شیء انجام دهد. این موضوع برای فایلهای Parquet (#23662)، CSV (#23961) و فرمت بومی داکدیبی (#24654) اعمال میشود، همچنین نوشتنهای ناهمگام Parquet (#23283) و حالتهای جدید MMAP و DIRECT_IO (#22988) اضافه شدهاند.
معماری ذخیرهسازی و پارسر
نسخه ۲.۰ فرمت ذخیرهسازی پیشفرض را به v2.0.0 ارتقا داده است (#22875). بزرگترین تغییر، ایندکسهای ART مدیریتشده توسط بافر (#21458, #23605) است. ایندکسها دیگر در حافظه پین نمیشوند، به این معنی که جداول ایندکسشده بزرگ فوراً باز شده و دادهها را بر حسب نیاز فراخوانی (page in) میکنند.
سایر بهبودها شامل موارد زیر است:
- متادیتای تنبل: متادیتای ستونها بهصورت تنبل (lazy) بارگذاری میشود (#22333) که سرعت باز شدن جداول عریض را افزایش میدهد.
- فشردهسازی: فشردهسازی رشتهای
DICT_FSSTاکنون بهطور پیشفرض فعال است (#23733). - حذفهای فشرده: عملیات حذف بهصورت فشردهتری ذخیره میشوند (#24336).
- اعتبارسنجی: اعتبارسنجی قویتری برای شناسایی فساد دادهها در هنگام خواندن انجام میشود.
تیم توسعه همچنین پارسر مشتقشده از PostgreSQL را کنار گذاشت و یک پارسر مدرن، توسعهپذیر و مبتنی بر PEG (#22194) جایگزین کرد. این تغییر به افزونهها اجازه میدهد به خودِ گرامر متصل شوند و احتمالاً سینتکسهای کاملاً جدیدی را به SQL اضافه کنند. همچنین پیامهای خطای دقیقتری با ذکر مکان دقیق منبع ارائه میدهد و حالت dialect_compatibility_mode = 'spark' را برای کاربران Spark فراهم میکند.
داخلیهای سبک و افزونهها
برای کاهش حجم و حذف اضافات، کتابخانه ICU بهطور کامل حذف شد. مناطق زمانی، تقویمها و collationها اکنون توسط یک افزونه بومی icu مدیریت میشوند (#24463, #24403). این کار ردپای دادههای منطقه زمانی را به حدود ۴۵ کیلوبایت (ساخته شده از دیتابیس IANA) کاهش داد و عملکرد را بهبود بخشید:
- تبدیل منطقه زمانی: تبدیل ۲۵ میلیون برچسب زمانی اکنون ۲.۲ برابر سریعتر است (۰.۱۱ ثانیه در مقابل ۰.۲۴ ثانیه).
- فیلتر کردن Collation: فیلتر کردن ۵ میلیون رشته با یک collation آلمانی ۲.۶ برابر سریعتر شده است (۰.۰۶ ثانیه در مقابل ۰.۱۵ ثانیه).
در نهایت، اکوسیستم افزونهها یک بازبینی پایداری را تجربه میکند. یک API سی (C API) پایدار جدید که از یک مشخصات YAML در دایرکتوری api_spec/ تولید شده است (#24135)، تضمین میکند که افزونههای نوشته شده در این نسخه، بدون نیاز به بازسازی در نسخههای آینده کار کنند. این شامل نسخهبندی یکپارچه نمادها (#24435)، مدیریتکنندههای تخصیص سفارشی (#23945) و لینک استاتیک افزونههای C API (#22251) است.
سازمانها اکنون میتوانند مخازن افزونههای مورد اعتماد خود را با استفاده از کلیدهای عمومی RSA میزبانی و امضا کنند (#24777). این امر توزیع امن و خصوصی را از طریق CREATE EXTENSION REPOSITORY my_repo FROM 'url' فراهم میکند. مخازن میتوانند روی مسیرهای محلی، HTTPS یا S3 میزبانی شوند و از طریق تابع جدولی duckdb_extension_repositories() بازرسی شوند. کاربران حتی میتوانند کلید عمومی را مستقیماً هنگام ایجاد ارسال کنند تا از اعتماد به شبکه بینیاز شوند: CREATE EXTENSION REPOSITORY my_repo FROM 's3://my-bucket/extensions' USING PUBLIC KEY '...';.
تحلیل: جابهجایی قدرت تحلیلی
با حرکت به سمت مدل سرور، داکدیبی دیگر فقط یک «SQLite محلی برای تحلیلها» نیست. این ابزار در حال تبدیل شدن به جایگزینی سبک برای انبارهای داده (Data Warehouses) عظیم است. توانایی انتقال پرسوجوها به پستگرس یا مایاسکیال در حالی که یک لایه تحلیلی با کارایی بالا در بالا حفظ میشود، یک معماری ترکیبی ایجاد میکند که برای تیمهای مهندسی متوسط بسیار جذاب است.
برای کاربر نهایی، جهش ۴۰ برابری در عملکرد پرسوجوهای بازگشتی و نوع بومی VARIANT به این معنی است که تحلیلهای پیچیده گراف و پردازش لاگها — کارهایی که معمولاً به ابزارهای تخصصی نیاز دارند — اکنون در SQL خالص قابل انجام هستند. این موضوع سد ورود به مهندسی داده پیشرفته را کاهش میدهد.
منتظر انتشار رسمی در پاییز و مستندات همراه آن درباره تغییرات ساختاری (breaking changes)، بهویژه در مورد فرمت جدید ذخیرهسازی و تکمیل انتقال سینتکس lambda باشید.




گفتگو