我有一个包含两个表格的数据库 - products
和items
。那里有一个1:M的关系,其中items.product_id
指向products.id
。
我有以下查询:
SELECT products.* FROM products
ORDER BY created_at desc
LIMIT 1
表现很好。但是,现在我加入了它的项目:
SELECT products.*
FROM products
JOIN items ON items.product_id = products.id
GROUP BY id
ORDER BY created_at desc
LIMIT 1
并且查询运行速度慢得令人无法接受(使用当前数据量约为5秒)
解释输出:
mysql> explain SELECT products.* FROM products GROUP BY id ORDER BY created_at desc LIMIT 1 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: products
type: index
possible_keys: PRIMARY,index_products_on_first_created_at
key: index_products_on_first_created_at
key_len: 5
ref: NULL
rows: 1
Extra: NULL
和
mysql> explain SELECT products.* FROM products JOIN items ON items.product_id = products.id GROUP BY id ORDER BY created_at desc LIMIT 1 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: products
type: index
possible_keys: PRIMARY,index_products_on_first_created_at
key: PRIMARY
key_len: 4
ref: NULL
rows: 261734
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: items
type: ref
possible_keys: index_items_on_product_id
key: index_items_on_product_id
key_len: 4
ref: foobar_development.products.id
rows: 1
Extra: Using index
2 rows in set (0,00 sec)
所以基本上,当我加入(和组)时,MySql不再使用created_at
的索引,从而破坏了它对结果进行正确排序的能力。我尝试使用id
+ created_at
创建组合索引,但查询计划会忽略它。 E.g:
alter table products add index foobar (id,created_at) ;
如何才能使此查询更好?