سؤال

هي الاستعلامات التالية فعالة في MYSQL:

SELECT * FROM table WHERE field & number = number; 
# to find values with superset of number's bits

SELECT * FROM table WHERE field | number = number; 
# to find values with subset of number's bits

... إذا تم إنشاء مؤشر للحقل؟

إذا لم يكن الأمر كذلك، هل هناك طريقة لجعلها تعمل بشكل أسرع؟

هل كانت مفيدة؟

المحلول

تحديث:

انظر هذا الإدخال في مدونتي للحصول على تفاصيل الأداء:


SELECT * FROM table WHERE field & number = number

SELECT * FROM table WHERE field | number = number

يمكن أن يكون هذا المؤشر فعال بطريقتين:

  1. لتجنب عمليات مسح الطاولة المبكرة (نظرا لأن القيمة للمقارنة موجودة في الفهرس نفسه)
    • للحد من مجموعة القيم التي تم فحصها.

لا شرط في الاستعلامات أعلاه هو sargable., ، هذا هو الفهرس لن يتم استخدامه لمسح النطاق (مع الشروط كما هي الآن).

ومع ذلك، النقطة 1 لا يزال يحمل، والفهرس يمكن أن يكون مفيدا.

إذا كان الجدول الخاص بك يحتوي، قل، 100 بايت كل صف في المتوسط، و 1,000,000 سجلات، ثم سيحتاج مسح الطاولة إلى المسح الضوئي 100 Mb البيانات.

إذا كان لديك فهرس (مع 4- مفتاح، 6Bebyte صف مؤشر وبعض النفقات العامة الداخلية)، سيحتاج الاستعلام إلى المسح الضوئي فقط 10 Mb البيانات بالإضافة إلى بيانات إضافية من الجدول إذا نجح المرشح.

  • الفحص الجدول هو أكثر كفاءة إذا كانت حالتك ليست انتقائية (لديك احتجاجات عالية لتتناسب مع الشرط).
  • يعد مسح الفهرس أكثر كفاءة إذا كانت حالتك انتقائية (لديك مسابقات منخفضة لتتناسب مع الحالة).

ستتطلب كل من هذه الاستفسارات مسح الفهرس بأكمله.

ولكن عن طريق إعادة كتابة AND استعلام يمكنك الاستفادة من تتراوح في الفهرس أيضا.

هذا الشرط:

field & number = number

يمكن فقط مطابقة الحقول إذا كانت أعلى بت من number تم تعيين مجموعة في field جدا.

ويجب عليك فقط تقديم هذا الشرط الإضافي للاستعلام:

SELECT  *
FROM    table
WHERE   field & number = number
        AND field >= 0xFFFFFFFF & ~((2 << FLOOR(LOG(2, 0xFFFFFFFF & ~number))) - 1)

سيستخدم هذا النطاق للتصفية الخشنة وحالة الترشيح الدقيق.

المزيد من البتات ل number هي غير مؤلفة في النهاية، كلما كان ذلك أفضل.

نصائح أخرى

أشك في أن المحسن سيؤدي إلى الرقم ...

ربما يمكنك الاتصال بشرح على هذه الاستعلامات وتأكيد تخمين التشاؤم الخاص بي. (تذكر بالطبع أن الكثير من قرارات خطة الاستعلام تستند إلى مثيل معين لقاعدة بيانات معينة، أي كميات متغيرة من البيانات و / خام مجرد بيانات مع ملف تعريف إحصائي مختلف قد تنتج خططا مميزة).

على افتراض أن الجدول لديه كمية كبيرة من الصفوف، وأن المعايير "bitwised" تظل انتقائية بما فيه الكفاية) يتحقق التحسين المحتمل عند تجنب عملية bitwise على كل صف واحد، عن طريق إعادة كتابة الاستعلام مع بناء (أو مع انضمام في

شيء من هذا القبيل (المفاهيمي، أي لم يتم اختباره)

CREATE TEMPORARY TABLE tblFieldValues
  (Field INT);

INSERT INTO tblFieldValues
   SELECT DISTINCT Field
   FROM table;

-- SELECT * FROM table WHERE field | number = number; 
-- now becomes
SELECT * 
FROM table t
WHERE field IN 
    (SELECT Field 
     FROM tblFieldValues 
     WHERE field | number = number); 

الفوائد الكاملة لنهج مثل هذه الحاجة إلى تقييم حالات الاستخدام المختلفة (كل منها مع عدد كبير من الصفوف في الجدول، نظرا لإخلاء "المكان المباشر" حيث الرقم = الرقم = الرقم "فعال بما فيه الكفاءة)، لكنني أظن هذا قد يكون أسرع بكثير. يمكن تحقيق مزيد من المكاسب إذا لم يتعين إعادة إنشاء "TBLFieldvalues" في كل مرة. إن إنشاء فعال لهذا الجدول بالطبع يعني فهرس في الحقل في الجدول الأصلي.

لقد جربت هذا بنفسي، وعمليات Bitwise ليست كافية لمنع MySQL من استخدام فهرس على عمود "الحقل". من المحتمل أن يكون هذا الفحص الكامل للمؤشر يحدث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top