【问题标题】:MySQL ORDER BY optimisation on rangeMySQL ORDER BY 优化范围
【发布时间】:2009-11-13 03:08:51
【问题描述】:

我希望 MySQL 使用索引对这些行进行排序。

SELECT
  identity_ID
FROM
  identity
WHERE
  identity_modified > 1257140905
ORDER BY
  identity_modified

但是,这是使用文件排序进行排序(不受欢迎)。

现在,如果我在此处省略 ORDER BY 子句,则行排序只是因为使用索引来满足 WHERE 子句。

所以,我可以通过省略 WHERE 子句来获得我想要的行为,但是我依靠 MySQL 的行为来使行按顺序到达,并且如果 MySQL 改变它,将来可能会被刺痛内部行为。

我该怎么办?有什么方法可以告诉 MySQL,由于索引是按顺序存储的(b-tree)它不需要文件排序吗?

表格如下(简化):

CREATE TABLE IF NOT EXISTS `identity` (
  `identity_ID`       int(11) NOT NULL auto_increment,
  `identity_modified` int(11) NOT NULL,
  PRIMARY KEY         (`identity_ID`),
  KEY                 `identity_modified` (`identity_modified`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

【问题讨论】:

  • 让我在这里澄清一下我的理解,您要对identity_modified而不是其他字段进行排序?或者我错过了重点
  • 重点是,我想检索自某个日期以来修改的所有记录,按上次修改日期排序。我不希望 MySQL 必须为此进行文件排序;它可能必须对表格的大部分进行排序。由于 MySQL 按顺序存储索引行,因此不需要文件排序。
  • 你能发布这个查询的解释吗?对我来说,它要么进行全面扫描和排序,要么使用索引而不进行排序(取决于获取的记录数)。

标签: mysql optimization range sql-order-by


【解决方案1】:

到目前为止,我的解决方案是去掉ORDER BY 子句,并在查询中添加FORCE INDEX (identity_modified)。这在理论上应该确保行按照它们在索引中存储的顺序返回。

这可能不是一个最佳实践的方法,但它似乎是我想要的唯一方法。

【讨论】:

    【解决方案2】:

    如果您将表类型更改为 INNODB,则不会有文件排序

    ALTER TABLE mydb.identity ENGINE = INNODB;

    但我不确定您的查询是否存在问题: http://forums.mysql.com/read.php?24,10738,10785#msg-10785

    在操作前后使用 EXPLAIN 运行您的原始查询。

    http://dev.mysql.com/doc/refman/5.0/en/using-explain.html

    【讨论】:

    • 是的,它在该列上有一个索引。它使用 WHERE 子句的索引,但没有使用索引进行排序。
    • 您能创建一个脚本以便我们重新创建表吗?上面的查询是完整的还是缺少什​​么?
    • 将表格定义添加到问题中。是的,上面的查询是完整的——我只需要按修改日期顺序排列的 identity_ID 值,其中修改日期大于某个值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    相关资源
    最近更新 更多