OOZOU
تواصلوا معنا
العودة إلى TIL
ruby on rails

دوال Postgres والاستعلامات غير القابلة للفهرسة (Non-sargable)

13 أكتوبر 2020

قد يؤدي استخدام دوال postgres داخل عبارة where إلى جعل الاستعلام non-sargable، أي غير قادر على الاستفادة من الفهارس.

بنية قاعدة البيانات

tracks has_many artists

استعلام Non-Sargable

استخدام الدالة LOWER يمنع محرك نظام إدارة قواعد البيانات (DBMS) من الاستفادة من الفهارس.

Track.joins(:artists).where('LOWER(tracks.display_name) LIKE ?', "eric clapton%").explain

Gather  (cost=1000.85..56714.32 width=4061)
   Workers Planned: 2
   ->  Nested Loop  (cost=0.85..55713.62 rows=3 width=4061)
         ->  Nested Loop  (cost=0.42..55708.37 rows=3 width=4069)
               ->  Parallel Seq Scan on tracks  (cost=0.00..55365.17 rows=41 width=4061)
                     Filter: (lower((display_name)::text) ~~* 'eric clapton%'::text)
               ->  Index Scan using index_artist_relations_on_artist_item_type_and_artist_item_id on artist_relations  (cost=0.42..8.36 rows=1 width=16)
                     Index Cond: (((artist_item_type)::text = 'Track'::text) AND (artist_item_id = tracks.id))
         ->  Index Only Scan using idx_35952_primary on artists  (cost=0.43..1.75 rows=1 width=8)
               Index Cond: (id = artist_relations.artist_id)

استعلام Sargable

تتيح إزالة الدالة LOWER لمحرك DBMS استخدام الفهارس، مما يؤدي إلى تنفيذ أسرع.

Track.joins(:artists).where('tracks.display_name ILIKE ?', "eric clapton%").explain

Nested Loop  (cost=1497.60..2695.43 width=4061)
   ->  Nested Loop  (cost=1497.17..2684.94 rows=6 width=4069)
         ->  Bitmap Heap Scan on tracks  (cost=1496.75..1873.05 rows=97 width=4061)
               Recheck Cond: ((display_name)::text ~~* 'eric clapton%'::text)
               ->  Bitmap Index Scan on index_tracks_on_display_name  (cost=0.00..1496.73 rows=97 width=0)
                     Index Cond: ((display_name)::text ~~* 'eric clapton%'::text)
         ->  Index Scan using index_artist_relations_on_artist_item_type_and_artist_item_id on artist_relations  (cost=0.42..8.36 rows=1 width=16)
               Index Cond: (((artist_item_type)::text = 'Track'::text) AND (artist_item_id = tracks.id))
   ->  Index Only Scan using idx_35952_primary on artists  (cost=0.43..1.75 rows=1 width=8)
         Index Cond: (id = artist_relations.artist_id)

الاستعلامات Sargable وNon-Sargable

الاستعلام sargable هو استعلام يمكنه استخدام فهرس لتسريع تنفيذه. فهو يسمح لمحرك DBMS بإجراء بحث في الفهرس (index seek)، وهو أسرع بكثير من مسح الجدول بأكمله. أما الاستعلام non-sargable فلا يمكنه استخدام الفهرس، لذا يكون أبطأ. ويأتي مصطلح sargable من عبارة "Search ARGument ABLE"، أي أن محرك DBMS يستطيع استخدام فهرس لتحسين الاستعلام. وفهم الفرق بين النوعين أساسي لتحسين أداء قاعدة البيانات.

الاستعلامات Non-Sargable

قد يكون للاستعلامات non-sargable أثر كبير في أداء الاستعلام، خاصة مع مجموعات البيانات الكبيرة. فعندما يكون الاستعلام non-sargable، يضطر محرك DBMS إلى إجراء مسح كامل للجدول أو مسح للفهرس، وكلاهما عملية ثقيلة. وقد يؤدي ذلك إلى بطء التنفيذ وارتفاع استهلاك المعالج وضعف أداء النظام عمومًا. لذا فإن اكتشاف الاستعلامات non-sargable وتحسينها أساسي لرفع كفاءة قاعدة البيانات وسرعة استجابتها.

الدوال في عبارة WHERE

قد يؤدي استخدام الدوال في عبارة WHERE إلى جعل الاستعلام non-sargable. ويحدث ذلك لأن محرك DBMS لا يستطيع استخدام فهرس لتحسين الاستعلام عند تطبيق دالة على عمود في عبارة WHERE. على سبيل المثال، لنأخذ الاستعلام SELECT FROM table WHERE UPPER(column) = 'VALUE'. هذا الاستعلام non-sargable لأن الدالة UPPER مطبقة على العمود، فلا يمكن استخدام الفهرس. ولجعله sargable، يمكنكم إزالة الدالة وإعادة كتابة الاستعلام على النحو التالي: SELECT FROM table WHERE column = 'VALUE'. عندها يستطيع محرك DBMS استخدام الفهرس ويصبح الاستعلام أسرع.

الفهارس وتحسين الاستعلامات

الفهارس عنصر أساسي في تحسين الاستعلامات، لأنها تتيح لمحرك DBMS العثور على البيانات بسرعة، وبالتالي تسريع الاستعلام. لكن لا يمكن استخدام الفهرس إلا إذا كان الاستعلام sargable. فإذا كان non-sargable، فلن يُستخدم الفهرس وسيكون الاستعلام أبطأ. لذا أنشئوا فهارس على الأعمدة المستخدمة في عبارة WHERE، وتأكدوا من أن استعلاماتكم sargable. سيحسّن ذلك أداء قاعدة بياناتكم بشكل كبير.

تحويل الشروط Non-Sargable

يُعد تحويل الشروط non-sargable إلى sargable خطوة من خطوات تحسين الاستعلامات. ويمكن تحويل الشرط non-sargable إلى sargable بإعادة كتابة الاستعلام لإزالة أي دوال أو عمليات تمنع استخدام الفهرس. على سبيل المثال، الاستعلام SELECT FROM table WHERE YEAR(date) = 2022 هو non-sargable لأن الدالة YEAR مطبقة على العمود date. ولجعله sargable، يمكنكم إعادة كتابته على النحو التالي: SELECT FROM table WHERE date >= '2022-01-01' AND date < '2023-01-01'. هذا الاستعلام المعاد كتابته sargable لأن محرك DBMS يستطيع استخدام فهرس على العمود date لتحسين الاستعلام، وسيكون أسرع.

المزيد حول ruby on rails

ruby on rails10 فبراير 2022

استخدام سياسات Pundit لإدارة المعاملات المسموح بها افتراضيًا ولكل إجراء

لإدارة المعاملات المسموح بها، يمكنكم إضافة permitted_attributes وpermitted_attributes_for_#{action} في السياسات، على سبيل المثال:

ruby on rails31 يناير 2022

استخدام `requestSubmit` لإرسال النماذج مع Turbo

يستمع Turbo إلى أحداث submit على النموذج. لذلك استخدموا دائمًا requestSubmit لإرسال النموذج عبر JS.

ruby on rails19 يناير 2022

تجاهل الـ gems المجمّعة في Rubocop وESLint ضمن GitHub Actions

غالبًا ما تثبّت مشاريع Rails الـ gems في مجلد vendor ضمن GitHub Actions، كي نتمكن من تخزينها مؤقتًا للتشغيلات المتتالية.

هل لديكم فكرة مشروع؟

يسعدنا أن نتعرّف على ما تبنونه.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد