The*_*_OP 5 mysql indexing django-models
我有我认为简单的查询,但它需要"永远".我对SQL优化不太满意,所以我想我可以问你们.
这是查询,使用EXPLAIN:
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;
Run Code Online (Sandbox Code Playgroud)
结果:
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, ''
Run Code Online (Sandbox Code Playgroud)
firm_location上的键:
Keyname                 Type    Unique  Packed  Field   Cardinality
PRIMARY                    BTREE    Yes     No      id      65818
firms_location_name_en     BTREE    No      No      name_en 65818
Run Code Online (Sandbox Code Playgroud)
firm_firmphonenumber上的键:
Keyname                     Type  Unique Packed  Field       Cardinality
PRIMARY                         BTREE Yes    No      id          85088
firms_firmphonenumber_firm_id   BTREE No     No      location_id 85088
Run Code Online (Sandbox Code Playgroud)
似乎(对我而言)mySQL拒绝使用firm_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;
Run Code Online (Sandbox Code Playgroud)
结果:
"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,""
Run Code Online (Sandbox Code Playgroud)
为什么现在决定使用这些?mySQL做出了一些奇怪的选择...任何见解都会有所帮助:)
最初,我有这些(缩写)模型:
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")
Run Code Online (Sandbox Code Playgroud)
更改Locaion的类的Meta.ordering字段以("name_en", )将查询修复为不具有虚假顺序.
这些事情往往是通过反复试验来实现的,但请尝试在 Firms_location.id 而不是 Firms_firmphonenumber.location_id 上订购。它们是相同的值,但 MySQL 可能会选择索引。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           489 次  |  
        
|   最近记录:  |