MySQL性能,内连接,如何避免使用临时和文件排序

Vin*_*nzo 5 mysql performance join inner-join

我有表1和表2。

表 1 PARTNUM - ID_BRAND partnum 是主键 id_brand 是“已索引”

表2 ID_BRAND - BRAND_NAME id_brand是主键brand_name是“indexed”

表 1 包含 100 万条记录,表 2 包含 1000 条记录。

我正在尝试使用 EXPLAIN 优化一些查询,经过多次尝试后我已经走到了死胡同。

EXPLAIN 
SELECT pm.partnum, pb.brand_name
FROM products_main AS pm 
LEFT JOIN products_brands AS pb ON pm.id_brand=pb.id_brand
ORDER BY pb.brand ASC 
LIMIT 0, 10
Run Code Online (Sandbox Code Playgroud)

查询返回此执行计划:

ID, SELECT_TYPE, TABLE, TYPE, POSSIBLE_KEYS, KEY, KEY_LEN , REF, ROWS, EXTRA
1, SIMPLE, pm, range, PRIMARY, PRIMARY, 1, , 1000000, Using where; Using temporary; Using filesort
1, SIMPLE, pb, ref, PRIMARY, PRIMARY, 4, demo.pm.id_pbrand, 1,
Run Code Online (Sandbox Code Playgroud)

MySQL查询优化器在执行计划中显示临时+文件排序。我怎样才能避免这种情况?

“EVIL”位于ORDER BY pb.brand ASC中。通过外部字段订购似乎是瓶颈。

eil*_*rra 0

首先,尝试更改products_brands表上的索引。删除 上现有的brand_name,并创建一个新的:

ALTER TABLE products_brands ADD INDEX newIdx (brand_name, id_brand)
Run Code Online (Sandbox Code Playgroud)

然后,该表将已经有一个“orderedByBrandName”索引,其中包含连接所需的 id,您可以尝试:

EXPLAIN
SELECT pb.brand_name, pm.partnum
FROM products_brands AS pb 
  LEFT JOIN products_main AS pm ON pb.id_brand = pm.id_brand
LIMIT 0, 10
Run Code Online (Sandbox Code Playgroud)

请注意,我还更改了查询中表的顺序,因此您可以从小开始。