سؤال

لدي فهرس m_idx على (k1,k2,k3)
إذا فعلت
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
أو
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1 IN (500,1000,1500 ...) AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 999

ولكن إذا حاولت استخدام نطاق على K1:
SELECT c1,c2,c3... FROM tb FORCE INDEX (m_idx) WHERE k1>=500 AND k2 IN(...) AND k2>2000 ORDER BY k1 LIMIT 1000;
Handler_read_next = 58035
في جميع الحالات ، يوضح أن المفتاح المستخدم هو m_idx
لكنني أعتقد أن ذلك في الحالة الثالثة m_idx لم يتم استخدامه (لدي أيضًا فهرس فقط على K1).
وإلا فإنني لا أفهم سبب قراءة أكثر من 1000 صف.
كنت أتوقع مسح المسح m_idx فهرس ، و ONLY the first 1000 الصفوف التي تلبي الشروط المراد قراءتها من الجدول.
لكن في الواقع ، أعتقد أنه بالنسبة للحالة الثالثة ، فإنه يقوم بمسح الفهرس ويتم قراءة تلك الصفوف التي تلبي حالة K1 من شروط السل و K2 و K3 بعد قراءة الصفوف من السل.
أنا استخدم: MySQL مع Myisam ، Windows 7 64 ، TB لديه صفوف 1 مل ؛
لذلك أسئلتي هي:
هل من الممكن تحديد النطاق على أقصى اليسار المؤشر؟
أو
أنا أفعل شيئًا آخر خاطئًا؟
شكرًا لك.

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

المحلول

  1. لا ليست كذلك.
  2. لا ، أنت تفعل كل شيء بشكل صحيح

http://dev.mysql.com/doc/refman/5.1/en/range-optimization.html ("7.3.1.3.2

لذلك لا يمكنك مساعدة Optimizer لأداء هذا الاستعلام بشكل أسرع.

وتجنب استخدام FORCE INDEX, ، بما أن المحسّن يعرف بشكل أفضل ما هو فهرس لاستخدامه.

ايضا:

k1>=500 AND k2 IN(...) AND k2>2000

اعتمادًا على أي جزء يعيد سجلات أقل ، إما k1>=500 أو k2 IN(...) AND k2>2000 (لست متأكدًا لماذا تحتاج > 2000 هنا ، بسبب يمكنك مقارنتها يدويًا ، قبل الإضافة إلى IN()) ، يمكنك أيضًا محاولة إنشاء الفهرس k2 (إذا k2 الجزء يعيد كمية أقل من السجلات).

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