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

标签 mysql sql optimization

我遇到过这样的情况:我在 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 显示使用索引条件;使用临时的;使用文件排序

我知道我应该避免使用 Usingtemporary; 进行查询。使用 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 last_order_date DESC

order by date_created desc 没有意义。

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

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

回到你原来的问题...

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

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

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

使用索引条件意味着InnoDB正在承担通用“Handler”通常所做的一些工作。 (这很好,但没什么大不了的。)但是,用 INDEX(product_id, date_created) 替换 INDEX(product_id) 可能会更好,因为它是“覆盖”,这将由使用索引表示。

“我对两个字段都有索引”——这与我推荐的复合索引不同。

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

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

关于mysql - 使用临时文件和文件排序总是不好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68425953/

相关文章:

java - 在 IDE Netbeans 中从 java 连接到 MySQL 数据库

sql - 在 Oracle 中解析电子邮件地址以计算 @ 符号前具有 3 个或更少字符的地址数

php - 有人可以向我解释这个 SQL 查询吗?

Sql查询优化和分析

MYSQL 选择大于 OR 的记录

MySQL:对表的所有行执行连接

c# - MySQL 返回列名而不是它们的内容

optimization - 哪些处理器支持 "Fast Short REP CMPSB and SCASB"

java - 如何优化solr索引

mysql - 我想结合两个nodejs程序以获得一个结果: specific CSV data filtered by type - how do I combine the code properly?