繁体   English   中英

使用临时和文件排序总是不好吗?

[英]is it always bad to have Using temporary and filesort?

我有一种情况,我在 where 子句中最多指定 100 个主键。

一个示例查询:

select  product_id, max(date_created) AS last_order_date
    from  orders
    where  product_id=28906
      or  product_id=28903
      or  product_id=28897
      or  product_id=28848
      or  product_id=28841
      or  product_id=28839
      or  product_id=28838
      or  product_id=28837
      or  product_id=28833
      or  product_id=28832
      or  product_id=28831
      or  product_id=28821
      or  product_id=28819
      or  product_id=28816
      or  product_id=28814
      or  product_id=28813
      or  product_id=28802
      or  product_id=28800
      or  product_id=28775
      or  product_id=28773
    group by  product_id
    order by  date_created desc

EXPLAIN 显示Using index condition; Using temporary; Using filesort Using index condition; Using temporary; Using filesort

我知道我应该避免Using temporary; Using filesort查询Using temporary; Using filesort Using temporary; Using filesort ,但是即使对于大型数据集,即使查询执行时间很快,我也必须避免使用它吗? 我已经给出了一个 ID 列表,所以这个查询是我能做的最好的。

如果我决定继续使用查询,我应该期待什么副作用或缺点?

解释输出:

1   SIMPLE  wc_order_product_lookup range   product_id  product_id  8   NULL    3   Using index condition; Using temporary; Using filesort

文件order by用于group byorder by 很难避免。 不过,您可能会发现inwhere子句有所帮助:

select product_id,  max(date_created)  AS last_order_date
from orders
where product_id in (28906, 28903, 28897, . . . )
group by product_id
order by date_created desc;

做戈登说的,但使用

ORDER BY last_order_date DESC

order by date_created desc没有意义。

如果列表“太长”,它可能会切换到表扫描。 可能是 MySQL 和 MariaDB 之间EXPLAIN的不同之处。 (结果集将是相同的。)

如果您执行EXPLAIN FORMAT=JSON SELECT ... ,您可能会发现有两种文件排序。

回到你原来的问题...

在某些情况下,“文件排序”和“使用临时”是必要的——尤其是你的情况。 在对结果进行GROUPs后, ORDER BY调用以GROUP BY未指定的方式进行排序。 需要存储数据并对其进行排序。

“文件排序”用词不当。 大多数情况下,行位于 RAM 中并且可以非常快速地排序。 对于非常大的结果集和其他复杂情况,实际上将使用“临时”“文件”。

优化器将您的ORs列表转换为一个IN就像 Gordon 的答案一样。 所以,这两种写法本质上没有区别。 (我发现IN更简洁更简洁。)

Using index condition意味着 InnoDB 正在承担通用“处理程序”通常所做的一些工作。 (这很好,但没什么大不了的。)但是,将INDEX(product_id)替换为INDEX(product_id, date_created)可能会更好,因为它是“覆盖”的,这将通过Using index指示。

“我有两个字段指数” -这是一样的,我推荐的综合指数。

您说的是“100 个主键”,但我怀疑您的意思是“辅助”键。 请提供SHOW CREATE TABLE orders来讨论这个问题。

我不同意老太太的故事:“应该避免使用临时查询;使用文件排序”。 这些只是你正在做的事情需要如此复杂的线索。 它很少可以“避免”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM