我有一个包含两个表的数据库 -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
,但查询计划忽略了它。例如:
alter table products add index foobar (id,created_at) ;
我该怎么做才能使这个查询更好地执行?