【问题标题】:MySQL Select & Limit computational complexityMySQL 选择和限制计算复杂度
【发布时间】:2017-08-09 19:39:44
【问题描述】:

假设我有一个这样定义的 mysql 表:

create table test_table(
id int(10) unsigned auto_increment primary key
/*, other attributes...*/
);

鉴于该表,我想像这样从中获取最后一条记录:

select * from test_table order by id desc limit 1;

它有效,但感觉有点粗略,它的复杂性是什么? 是不是 O(log(n)) 因为 "limit" 和 "order by" 在 select 之后执行?

有没有更好的方法从自动递增表中选择最后一条记录?

【问题讨论】:

  • 应该是 O(1)。我稍后会尝试解释更多。此外,每个 id 获取都可以是 O(1),而不仅仅是最后一条记录。然而,这取决于实现。
  • 如果列被索引,那么这将是 O(1)。

标签: mysql select sql-order-by complexity-theory sql-limit


【解决方案1】:

我想我明白了。
我最初的问题与“选择和限制”相关联,但实际上这适用于所有查询。

MySQL 提供“分析”关键字。 您可以在终端上调用它,然后执行您的查询;它将输出一些有关执行细节的元数据。

这是一个在我的问题中使用表格的示例(我将其名称更改为“comment”,并将其 PK 更改为“commentid”以提供一些上下文):

 analyze
 select * from comment order by commentid desc limit 1;

以下是输出:

“rows”告诉您查询迭代了多少行,“r_rows”是结果行。
这就是我一直在寻找的。
我的印象是“限制”关键字会以某种方式优化查询。没有。

另一方面,你也可以使用 MAX() 来获取最后一行

 analyze
 select * from comment where commentid=(select max(commentid) from comment);

主查询显然只迭代了 1 行,但子查询应该是两者中最复杂的选择,所以我对其进行了分析:

 analyze
 select max(commentid) from comment;

给了我:

这并没有告诉我太多,除了“额外的”描述,它说:“选择优化掉的表”。

我查了一下,已经是answered question on stack

从我目前收集到的信息来看,该描述意味着 MAX 实际上并不计算表的行数,而是使用由 sql 引擎管理的存储值。

它仅在列具有“auto_increment”时才有效。

接受的答案还说它只适用于 MyISAM 表,但我正在 InnoDB 表上运行这些测试,优化似乎正在发挥作用。

以下是详细信息:

 SELECT PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_TYPE_VERSION, PLUGIN_LIBRARY, PLUGIN_LIBRARY_VERSION, PLUGIN_AUTHOR
   FROM information_schema.PLUGINS
  WHERE PLUGIN_NAME = 'innodb';

PS:您可能想知道是否这样做:

ALTER TABLE comment AUTO_INCREMENT = 999;

搞砸了优化。
答案是否定的,它不会,将 AUTO_INCREMENT 设置为某个值只会影响下一个条目。
自己试试,修改AUTO_INCREMENT值然后运行

select max(commentid) from comment;

你仍然会得到正确的值。

【讨论】:

    【解决方案2】:

    您也可以使用这种方法获得所需的输出。

    SELECT * FROM test_table where id=(select max(id) from test_table);
    

    希望对你有所帮助。

    【讨论】:

    • 这似乎可行,但是 max() 函数的复杂性是多少?它不会遍历所有索引以找到最高的索引吗?感谢您的回复!
    • @RazvanTanase 您不应将此答案标记为已接受的答案。因为他根本没有提到时间复杂度。我在谷歌上搜索限制的时间复杂度并发现了这个问题。不幸的是,这不是一个真正的答案。
    猜你喜欢
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-04
    • 2012-12-31
    • 2019-03-11
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多