我有一个带有int字段的表,我们称之为createTime 该表包含数百万条记录。 现在我想运行查询:

select * from `table` order by `createTime` desc limit 500000, 10

我已经为createTime创建了一个索引,但查询运行速度很慢。 什么原因? 我怎样才能改进它?

这是EXPLAIN所说的:

id 1
select_type simple
table table
type index
possible_keys null
key createTime
key_len 4
ref null
rows 500010
extra

至于偏移量,当它很小时它的工作速度要快得多。

===============>>#1 票数:9 已采纳

一般规则: 避免大表的OFFSET

[A]偏移量增加,查询执行所需的时间逐渐增加,这可能意味着处理非常大的表将花费很长时间。 原因是因为offset对表中没有索引的行的物理位置起作用。 因此,要在偏移量x处找到行,数据库引擎必须遍历从0到x的所有行。

一般的经验法则是“绝不使用限制条款中的偏移量”。 对于小型表,您可能不会注意到任何差异,但对于超过一百万行的表,您将看到巨大的性能提升。

===============>>#2 票数:2

如果您有一个唯一的列,则可以加快速度。 理想情况下,它将是createTime本身:

SELECT "table".*
  FROM "table"
  INNER JOIN (
    SELECT "createTime"
      FROM "table"
      ORDER BY "createTime" DESC
      LIMIT 500000, 10
  ) AS "limit" ON "table"."createTime" = "limit"."createTime"

如果createTime不是唯一的,但是您有另一个唯一的列,那么您可能会发现需要在createTime和另一列上创建复合索引,以便此查询有效运行:

SELECT "table".*
  FROM "table"
  INNER JOIN (
    SELECT "createTime", "unique"
      FROM "table"
      ORDER BY "createTime" DESC
      LIMIT 500000, 10
  ) AS "limit" ON "table"."unique" = "limit"."unique"

===============>>#3 票数:0

我认为索引不会改变任何东西。 使用offset, limit意味着“读取偏移+限制数据集并丢弃它们(数量偏移)”。 如果你真的想要为这么大的表分页或类似的东西,你应该使用一种方法,你可以在查询的WHERE部分限制你的结果。 这些类型的查询将受益于正确的索引。

使用日期时,解决方案可能是使用时隙来显示数据。 例如,您可以显示一周中每一天的链接,并构建您的查询,例如“WHERE createDate>'2011-12-11'and crateDate << 2011-12-12'。

  ask by Sebastian Nowak translate from so

未解决问题?本站智能推荐: