【问题标题】:Will this query work as expected?此查询会按预期工作吗?
【发布时间】:2012-05-01 23:34:52
【问题描述】:

我有一个只有一列的 mysql 表,该列有一些 3 个字母的单词和一些 4 个字母的单词,还有一些 5 和 6 个字母的单词。

我希望一个查询首先从所有 3 个字母的单词中随机选择,当它们全部消失时,然后转到 4 个字母的单词,依此类推。

这是我的查询:

SELECT `word` FROM `words` ORDER BY LENGTH(`word`) ASC, RAND() LIMIT 1

到目前为止,在我尝试过的几次中,它都按预期工作,但我想确保它总是这样工作。

【问题讨论】:

  • 您的查询对我来说看起来不错,但我希望表很小,因为 MySQL 每次都会扫描所有行,然后使用文件排序,全部返回一行。
  • @Ami 大约有 4k-5k 条记录。用单词的长度添加另一列会更有效吗?然后做ORDER by wordLength ASC, RAND()
  • @Click Upvote 是的,在阅读您的评论问题之前,我正准备告诉您完全相同的事情。请解释“当他们全部消失时”是什么意思。您是否在返回后删除行?
  • 不,不幸的是,这无济于事,因为 RAND() 仍然需要全表扫描和文件排序。在下面寻找我的扩展答案,即将推出......
  • @Tiberiu-IonuțStan 是的,我是,但它们会根据用户的要求被删除,而不是一次性删除

标签: mysql database


【解决方案1】:

您的查询对我来说看起来不错,但我希望表很小,因为 MySQL 每次都会扫描所有行,然后使用文件排序,全部返回一行。

添加wordlength 列并为其编制索引不会改进查询,因为ORDER BY RAND() 函数会使索引的使用无效。

考虑将单词拆分为单独的表格,具体取决于它们的长度,至少您将只扫描所有行以查找相同长度的单词。先从three_letter_words表中选择,如果没有结果,再从four_letter_words表中选择,以此类推。

【讨论】:

  • 如果我做了Select.. WHERE wordLength = 3 ORDER BY RAND(),当3个字母单词用完,然后WHERE wordLength = 4等等?
  • @ClickUpvote,啊,是的!我只是在想同样的事情。这比管理多个表更容易(在代码中),但代价是使索引保持最新。我认为这是一个很好的妥协,不想过度优化,让自己很难受。如果您使用 InnoDB,请使用自动递增的主键进行快速插入。
  • 为什么使用主键可以加快插入速度?
  • @ClickUpvote,忘了我说的,稍后再回来优化。 :)
猜你喜欢
  • 2012-11-13
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 2012-11-18
相关资源
最近更新 更多