【问题标题】:Optimizing a SQL query by only looking in the last X rows (Not simply LIMIT)通过仅查看最后 X 行来优化 SQL 查询(不仅仅是 LIMIT)
【发布时间】:2013-08-08 16:56:42
【问题描述】:

我想对一个非常大的表执行 SQL 查询。但是,我只需要查看最后 100,000 行。目前:

SELECT * FROM bigtable WHERE columna='foobar' ORDER BY id DESC LIMIT 10 

我也想做同样的事情,但让它只在最后的 X ids 中查找。

编辑:先选择 100k 行然后从中选择它不是解决方案。这会选择完整的前 100k 行,即使已找到超过 10 个所需的行。这让它变慢了。

【问题讨论】:

  • @gladoscc 你可以在 sql server 中做这样的事情 select top 100000 columnname from bigtable where columna='foobar' order by id desc
  • @Petr R.:这在我的情况下不起作用,因为它会选择完整的 100k 行,即使它已经找到了 10 行而没有限制。我需要的是能够使查询超时。

标签: mysql sql


【解决方案1】:

试试

select * from 
(
  SELECT * 
  FROM bigtable 
  ORDER BY id DESC
  LIMIT 100000
) x
where columna = 'foobar' 
order by id desc
limit 10

SQLFiddle demo

如果您的查询速度很慢,请在 columna 上添加索引。

【讨论】:

  • 此查询完全符合您的要求。再仔细阅读一遍,试一试
  • 您编辑了查询,但这实际上速度较慢。因为通常它不需要查看完整的 100000 行。
  • 然后将其限制为较少的行数。它被称为延迟行查找,您可以用谷歌搜索它以了解它的工作原理和原因。这是使其高效的唯一方法,除非您知道需要检查的主键的值,以便您可以限制正在查看的索引范围。此外,请确保您正确配置了 MySQL,因为如果您运行默认配置 - 再多的查询优化也无济于事。
【解决方案2】:

bigtable(columna, id上创建一个复合索引)。

MySQL 应该足够聪明,可以在索引中查找columna 中的值并按第二个键排序。这在documentation 中有解释。

【讨论】:

  • 我是通过 id 而非 columna 来下单的。
  • @gladoscc 。 . .您正在对columna 进行过滤并在id 上进行排序。这就是为什么 MySQL 会为两者都使用这个索引。
【解决方案3】:

在数据库中,您不能执行检查“最后 x 行”的查询。关系数据库不保证行以特定顺序物理存储。因此 SQL 将不允许您表达这一点。如果您可以根据行中包含的数据将其转换为实际约束,那么这将是可能实现的。

以您的示例为例,数据库要做的最糟糕的操作是在返回数据之前对完整结果集进行排序。这与limit 子句无关,因为只有在遍历所有行并对它们进行排序之后,您才能知道哪些行具有最高的 id。

但是,如果存在具有columnaid 的索引,则按照该顺序,数据库引擎应该使用已排序的索引来更快地遍历行,从而加快响​​应时间。

【讨论】:

  • 我已经按该顺序添加了一个带有 columna 和 id 的索引,但是性能仍然很慢。有没有办法让查询超时并在 X 秒后返回它所拥有的任何内容?
猜你喜欢
  • 2020-10-05
  • 2013-05-22
  • 1970-01-01
  • 2023-03-27
  • 2021-06-12
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2015-05-09
相关资源
最近更新 更多