لماذا الخلية تتجاهل مفتاح "واضح" لاستخدامها في هذا بسيط انضمام الاستعلام؟

StackOverflow https://stackoverflow.com/questions/804258

  •  03-07-2019
  •  | 
  •  

سؤال

ولدي ما كان يعتقد أن يكون استعلام بسيط، لكنه يأخذ "إلى الأبد". أنا لست كبيرة مع تحسينات SQL، حتى ظننت أنني يمكن أن تسأل يا رفاق.

إليك الاستعلام، مع شرح:

EXPLAIN SELECT *
    FROM `firms_firmphonenumber`
    INNER JOIN `firms_location` ON (
        `firms_firmphonenumber`.`location_id` = `firms_location`.`id`
    )
    ORDER BY
         `firms_location`.`name_en` ASC,
         `firms_firmphonenumber`.`location_id` ASC LIMIT 100;

والنتيجة:

id, select_type,       table,           type,  possible_keys,                     key,                           key_len, ref, rows, Extra
1,  'SIMPLE',     'firms_location',    'ALL',  'PRIMARY',                        '',                            '',             '', 73030, 'Using temporary; Using filesort'
1,  'SIMPLE', 'firms_firmphonenumber', 'ref', 'firms_firmphonenumber_firm_id', 'firms_firmphonenumber_firm_id', '4', 'citiadmin.firms_location.id', 1, ''

ومفاتيح على firms_location:

Keyname                 Type    Unique  Packed  Field   Cardinality
PRIMARY                    BTREE    Yes     No      id      65818
firms_location_name_en     BTREE    No      No      name_en 65818

ومفاتيح على firms_firmphonenumber:

Keyname                     Type  Unique Packed  Field       Cardinality
PRIMARY                         BTREE Yes    No      id          85088
firms_firmphonenumber_firm_id   BTREE No     No      location_id 85088

ويبدو (بالنسبة لي) أن الخلية يرفض استخدام المفتاح الأساسي للجدول firms_location ل- ولكن ليس لدي أي فكرة عن السبب

وأي مساعدة ستكون <م> كثير تقدير.


تحرير بعد حل نشرت

ومع الأمر تغير حسب:

EXPLAIN SELECT *
    FROM `firms_firmphonenumber`
    INNER JOIN `firms_location` ON (
        `firms_firmphonenumber`.`location_id` = `firms_location`.`id`
    )
    ORDER BY
         `firms_location`.`name_en` ASC,
         `firms_location`.id ASC LIMIT 100;
         #`firms_firmphonenumber`.`location_id` ASC LIMIT 100;

والنتيجة:

"id","select_type","table","type","possible_keys","key","key_len","ref","rows","Extra"
1,"SIMPLE","firms_location","index","PRIMARY","firms_location_name_en","767","",100,""
1,"SIMPLE","firms_firmphonenumber","ref","firms_firmphonenumber_firm_id","firms_firmphonenumber_firm_id","4","citiadmin.firms_location.id",1,""

لماذا انها قررت استخدام هذه الآن؟ الخلية يجعل بعض الخيارات ونيف ... وأي فكرة تساعد مرة أخرى:)


تحرير مع التفاصيل من جانغو

وكتبت، وكان لي هذه (مختصر) نماذج:

class Location(models.Model):
    id = models.AutoField(primary_key=True)
    name_en = models.CharField(max_length=255, db_index=True)
    class Meta:
        ordering = ("name_en", "id")

class FirmPhoneNumber(models.Model):
    location = models.ForeignKey(Location, db_index=True)
    number = PhoneNumberField(db_index=True)
    class Meta:
        ordering = ("location", "number")

وتغيير الحقل Meta.ordering فئة Locaion في ل("name_en", ) الثابتة الاستعلام ليست لديها ترتيب زائفة من قبل.

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

المحلول

وهذه الأمور تميل إلى أن تكون عن طريق التجربة والخطأ، ولكن حاول طلب في firms_location.id بدلا من firms_firmphonenumber.location_id. وهي نفس القيمة، ولكن قد الخلية ثم تلتقط على المؤشر.

نصائح أخرى

ومن استخدامه، للانضمام. هذا هو قيمة 'citiadmin.firms_location.id' في العمود ref. ومن لا تظهر في possible_keys وkey لأن لديك أي جملة WHERE وانها تعكس فقط مفاتيح المتوفرة لديها لجملة ORDER BY.

إذا كنت ترغب في تسريع الاستعلام الخاص بك، في محاولة فهرسة name_en.

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

أولا، يمكنك أن تفعل USE لإجبارها على استخدام الفهرس الذي تحدده. أيضا، حاول القيام والأمثل للتأكد من يقدر أصل صحيح. (انا التخمين كنت تستخدم INNO، الذي يقدر في سلسلة من "الغطس" عشوائية؛. إذا كان هذا هو MYISAM، الذي لا يعرف الواقع، ثم أتساءل لماذا تبدو العلاقة الأساسية كما هو الحال)

ولا تهتم فهرسة اسم أو الخ MySQL سيتم استخدام مؤشر واحد فقط لكل جدول في الانضمام، من أي وقت مضى، وسوف مؤشر الاعظم فقط عنه.

ومقدار البيانات؟ إلا إذا كان بعض الصفوف، فإن معظم قواعد البيانات يفعل مسح الجدول بغض النظر عن الأرقام القياسية لديك

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