查询
SELECT SQL_CALC_FOUND_ROWS wp29174960179_posts.*
FROM wp29174960179_posts
JOIN wp29174960179_plugin_wpf_products_attribute_79_numbers pan ON pan.product_id = wp29174960179_posts.ID
WHERE pan.number BETWEEN 10 and 10000
ORDER BY wp29174960179_posts.post_date ASC LIMIT 0, 9;
此查询很慢(耗时2秒)。 预期执行时间 <= 100ms
wp29174960179_plugin_wpf_products_attribute_79_numbers
表中有 80 000条记录。
wp29174960179_posts
表中的 100,000条记录
wp29174960179_plugin_wpf_products_attribute_79_numbers
表有 2个索引
ix__number__product_id (product_id, number)
ix__product_id__number (number, product_id)
*wp29174960179_posts
有索引, ID 字段
尽管有这些索引。查询需要 2-3 秒
SQL完整代码段链接:
https://www.db-fiddle.com/f/4Vk97FhArBVJ1Eb1BAubNB/0#&togetherjs=8KQQacE4Vt
答案 0 :(得分:3)
看起来 您在帖子和平移之间具有1-N的关系,并且您试图获取帖子中平移行中存在的满足给定条件的帖子。
如果是这样,您可以尝试使用EXISTS
子查询来重写查询:
select p.*
from wp29174960179_posts p
where exists (
select 1
from wp29174960179_plugin_wpf_products_attribute_79_numbers n
where n.product_id = p.id and n.number between 10 and 10000
)
order by p.post_date
limit 9
此技术避免了在外部查询中进行聚合的需求。该查询应该能够利用wp29174960179_plugin_wpf_products_attribute_79_numbers(product_id, number)
上的索引。
答案 1 :(得分:1)
我的猜测是外部排序导致了性能问题。您的查询和索引看起来很合理。问题是:我们可以欺骗MySQL避免排序吗?
从GMB建议的重写开始。它还具有不返回重复值的优点:
select p.*
from wp29174960179_posts p
where exists (select 1
from wp29174960179_plugin_wpf_products_attribute_79_numbers n
where n.product_id = p.id and
n.number between 10 and 10000
)
order by p.post_date
limit 9;
然后尝试以下索引:
wp29174960179_posts(post_date, id)
wp29174960179_plugin_wpf_products_attribute_79_numbers(product_id, number)
希望可以按post_date
顺序扫描posts表,并返回前9个匹配的行。手指交叉。