چرا برای صفحه بندی روی کلیدها به پشتیبانی ابزاری نیاز دارید؟

سلام به همه! من یک توسعه دهنده باطن هستم که میکروسرویس ها را در جاوا + Spring می نویسم. من در یکی از تیم های داخلی توسعه محصول در Tinkoff کار می کنم.

چرا برای صفحه بندی روی کلیدها به پشتیبانی ابزاری نیاز دارید؟

در تیم ما، سوال بهینه سازی پرس و جوها در یک DBMS اغلب مطرح می شود. شما همیشه می‌خواهید کمی سریع‌تر باشید، اما همیشه نمی‌توانید با شاخص‌هایی که با دقت ساخته شده‌اند، از پس آن برآیید - باید به دنبال راه‌حل‌هایی باشید. در طی یکی از این سرگردانی ها در سراسر وب در جستجوی بهینه سازی های معقول هنگام کار با پایگاه های داده، متوجه شدم وبلاگ بی پایان مفید مارکوس وایناند، نویسنده SQL Performance Explained. این نوع نادری از وبلاگ است که می توانید تمام مقالات را پشت سر هم بخوانید.

می خواهم مقاله کوتاهی از مارکوس را برای شما ترجمه کنم. تا حدودی می توان آن را یک مانیفست نامید که به دنبال جلب توجه به مشکل قدیمی اما همچنان مرتبط عملکرد عملیات افست طبق استاندارد SQL است.

در جاهایی با توضیحات و نظرات نویسنده را تکمیل می کنم. من به همه این مکان ها به عنوان "تقریبا" اشاره خواهم کرد. برای وضوح بیشتر

معرفی کوچک

من فکر می کنم بسیاری از مردم می دانند که کار با انتخاب صفحه از طریق افست چقدر مشکل ساز و کند است. آیا می دانستید که می توان آن را به راحتی با طراحی کارآمدتر جایگزین کرد؟

بنابراین، کلمه کلیدی افست به پایگاه داده می گوید که از n رکورد اول در درخواست صرفنظر کند. با این حال، پایگاه داده همچنان باید این n رکورد اول را از دیسک، به ترتیب داده شده بخواند (توجه داشته باشید: در صورت مشخص بودن مرتب سازی را اعمال کنید)، و تنها در این صورت امکان برگرداندن رکوردها از n+1 به بعد وجود خواهد داشت. جالب ترین چیز این است که مشکل در پیاده سازی خاص در DBMS نیست، بلکه در تعریف اصلی طبق استاندارد است:

سطرها ابتدا بر اساس مرتب‌سازی می‌شوند و سپس با حذف تعداد ردیف های مشخص شده در از آغاز…
-SQL:2016, Part 2, 4.15.3 جداول مشتق شده (توجه: در حال حاضر بیشترین استفاده استاندارد است)

نکته کلیدی در اینجا این است که افست یک پارامتر واحد را می گیرد - تعداد رکوردهایی که باید رد شوند، و تمام. پس از این تعریف، DBMS فقط می تواند تمام رکوردها را بازیابی کند و سپس موارد غیر ضروری را دور بریزد. بدیهی است که این تعریف از افست ما را مجبور به انجام کارهای اضافی می کند. و حتی مهم نیست که SQL باشد یا NoSQL.

فقط کمی درد بیشتر

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

چرا برای صفحه بندی روی کلیدها به پشتیبانی ابزاری نیاز دارید؟

هنگامی که از افست برای پرش از رکوردهای صفحات قبلی استفاده می شود، در شرایطی که یک رکورد جدید بین خواندن صفحات مختلف اضافه می شود، به احتمال زیاد موارد تکراری دریافت خواهید کرد (توجه: زمانی که ما صفحه به صفحه را با استفاده از ترتیب به ساختار می خوانیم، امکان پذیر است. در وسط خروجی ما ممکن است یک ورودی جدید دریافت کند).

شکل به وضوح این وضعیت را نشان می دهد. پایه 10 رکورد اول را می خواند، پس از آن یک رکورد جدید درج می شود که تمام رکوردهای خوانده شده را با 1 جبران می کند. سپس پایه یک صفحه جدید از 10 رکورد بعدی می گیرد و نه آنطور که باید از یازدهم، بلکه از صفحه شروع می شود. 11، تکرار این رکورد. ناهنجاری های دیگری در استفاده از این عبارت وجود دارد، اما این رایج ترین است.

همانطور که قبلاً متوجه شدیم، اینها مشکلات یک DBMS خاص یا پیاده سازی آنها نیست. مشکل در تعریف صفحه بندی بر اساس استاندارد SQL است. ما به DBMS می گوییم که کدام صفحه را واکشی کند یا چند رکورد را رد کند. پایگاه داده به سادگی قادر به بهینه سازی چنین درخواستی نیست، زیرا اطلاعات بسیار کمی برای آن وجود دارد.

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

  • کلمه کلیدی افست همانطور که قبلا ذکر شد است.
  • ساخت دو کلمه کلیدی محدودیت [offset] را دارد (اگرچه خود محدودیت چندان بد نیست).
  • فیلتر کردن با کران های پایین، بر اساس شماره گذاری ردیف (به عنوان مثال، row_number()، rownum، و غیره).

همه این عبارات به سادگی به شما می گویند که چند خط را رد کنید، بدون اطلاعات اضافی یا زمینه.

در ادامه این مقاله از کلمه کلیدی افست به عنوان خلاصه همه این گزینه ها استفاده می شود.

زندگی بدون آفست

حالا بیایید تصور کنیم که دنیای ما بدون این همه مشکل چگونه خواهد بود. به نظر می رسد که زندگی بدون افست چندان دشوار نیست: با انتخاب، می توانید تنها ردیف هایی را انتخاب کنید که ما هنوز ندیده ایم (توجه داشته باشید: آنهایی که در صفحه قبل نبودند)، با استفاده از یک شرط در کجا.

در این مورد، ما از این واقعیت شروع می کنیم که انتخاب ها بر روی یک مجموعه مرتب شده (ترتیب قدیمی خوب توسط) اجرا می شوند. از آنجایی که مجموعه‌ای مرتب داریم، می‌توانیم از یک فیلتر نسبتاً ساده استفاده کنیم تا فقط داده‌هایی را که در پشت آخرین رکورد صفحه قبلی قرار دارند، بدست آوریم:

    SELECT ...
    FROM ...
    WHERE ...
    AND id < ?last_seen_id
    ORDER BY id DESC
    FETCH FIRST 10 ROWS ONLY

این اصل کل این رویکرد است. البته، هنگام مرتب‌سازی بر اساس ستون‌های مختلف، همه چیز سرگرم‌کننده‌تر می‌شود، اما ایده همچنان یکسان است. لازم به ذکر است که این طرح برای بسیاری قابل اجرا است NoSQL-تصمیمات

این رویکرد روش جستجو یا صفحه‌بندی مجموعه کلید نامیده می‌شود. این مشکل نتیجه شناور را حل می کند (توجه داشته باشید: وضعیت نوشتن بین صفحات خوانده شده قبلا توضیح داده شد) و، البته، چیزی که همه ما دوست داریم، سریعتر و پایدارتر از افست کلاسیک کار می کند. ثبات در این واقعیت نهفته است که زمان پردازش درخواست متناسب با تعداد جدول درخواستی افزایش نمی یابد (توجه داشته باشید: اگر می خواهید در مورد کار روش های مختلف صفحه بندی بیشتر بدانید، می توانید از طریق ارائه نویسنده نگاه کنید. همچنین می توانید معیارهای مقایسه ای برای روش های مختلف را در آنجا پیدا کنید).

یکی از اسلایدها در مورد آن صحبت می کندکه صفحه بندی با کلیدها، البته، قادر مطلق نیست - محدودیت های خود را دارد. مهمترین آن این است که او توانایی خواندن صفحات تصادفی را ندارد (توجه داشته باشید: به طور متناقض). با این حال، در دوران پیمایش بی پایان (توجه: در قسمت جلویی)، این چنین مشکلی نیست. مشخص کردن شماره صفحه برای کلیک کردن به هر حال تصمیم بدی در طراحی UI است (توجه: نظر نویسنده مقاله).

در مورد ابزارها چطور؟

صفحه بندی روی کلیدها اغلب به دلیل عدم پشتیبانی ابزاری برای این روش مناسب نیست. اکثر ابزارهای توسعه، از جمله چارچوب های مختلف، به شما اجازه نمی دهند دقیقاً نحوه صفحه بندی را انتخاب کنید.

وضعیت با این واقعیت تشدید می شود که روش توصیف شده نیاز به پشتیبانی سرتاسری در فناوری های مورد استفاده دارد - از DBMS تا اجرای درخواست AJAX در مرورگر با پیمایش بی پایان. به جای اینکه فقط شماره صفحه را مشخص کنید، اکنون باید مجموعه ای از کلیدها را برای همه صفحات به طور همزمان مشخص کنید.

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

(توجه: برخی از لینک ها به دلیل اینکه در زمان ترجمه برخی از کتابخانه ها از سال 2017-2018 به روز نشده بودند حذف شدند. در صورت تمایل می توانید به منبع اصلی مراجعه کنید.)

در این لحظه است که به کمک شما نیاز است. اگر چارچوبی را توسعه می‌دهید یا از آن پشتیبانی می‌کنید که از صفحه‌بندی استفاده می‌کند، از شما می‌خواهم، از شما می‌خواهم که پشتیبانی بومی برای صفحه‌بندی روی کلیدها ارائه دهید. اگر سوالی دارید یا نیاز به کمک دارید، خوشحال خواهم شد کمک کنم (فروم, توییتر, فرم تماس) (توجه: با توجه به تجربه من با مارکوس، می توانم بگویم که او واقعا مشتاق است که این موضوع را گسترش دهد).

اگر از راه‌حل‌های آماده‌ای استفاده می‌کنید که فکر می‌کنید شایستگی پشتیبانی برای صفحه‌بندی توسط کلید را دارند، در صورت امکان یک درخواست ایجاد کنید یا حتی راه‌حل آماده ارائه دهید. همچنین می توانید به این مقاله لینک دهید.

نتیجه

دلیل اینکه چنین رویکرد ساده و مفیدی مانند صفحه بندی توسط کلیدها گسترده نیست این نیست که اجرای آن از نظر فنی دشوار است یا نیاز به تلاش زیادی دارد. دلیل اصلی این است که بسیاری به دیدن و کار با افست عادت دارند - این رویکرد توسط خود استاندارد دیکته شده است.

در نتیجه، افراد کمی به تغییر رویکرد صفحه بندی فکر می کنند و به همین دلیل، پشتیبانی ابزاری از چارچوب ها و کتابخانه ها ضعیف است. بنابراین، اگر ایده و هدف صفحه بندی بدون افست به شما نزدیک است، به گسترش آن کمک کنید!

منبع: https://use-the-index-luke.com/no-offset
نویسنده: مارکوس ویاند

منبع: www.habr.com

اضافه کردن نظر