【问题标题】:How to speed up MYSQL Query with JOIN and BETWEEN where clause?如何使用 JOIN 和 BETWEEN where 子句加速 MYSQL 查询?
【发布时间】:2020-07-02 06:28:50
【问题描述】:

查询

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 秒)。 预期执行时间

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)

ID字段的*wp29174960179_postsindex

尽管有这些索引。查询需要 2-3

SQL 完整代码片段链接:

https://www.db-fiddle.com/f/4Vk97FhArBVJ1Eb1BAubNB/0#&togetherjs=8KQQacE4Vt

【问题讨论】:

  • SQL_CALC_FOUND_ROWS 成本很高。看看没有它时它的运行速度有多快。

标签: mysql sql performance join query-optimization


【解决方案1】:

看起来您在帖子和 pan 之间有 1-N 关系,并且您正在尝试获取 pan 中存在满足给定条件的行的帖子。

如果是这样,您可以尝试使用 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) 上的索引。

【讨论】:

    【解决方案2】:

    我的猜测是外部排序导致了性能问题。您的查询和索引看起来很合理。问题是:我们可以欺骗 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个匹配的行。手指交叉。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      相关资源
      最近更新 更多