0

在 Rails 3.2.13 应用程序中,我使用 query_reviewer gem 来提高我的数据库性能。

生成 SQL 的代码是:

@seo_keywords = SeoKeyword.order("category, keyword")

它生成了以下 SQL 警告:

MSG: No index was used here. In this case, that meant scanning 64 rows.
SQL: SELECT SQL_NO_CACHE `seo_keywords`.* FROM `seo_keywords` ORDER BY category, keyword

所以我生成了以下数据库迁移:

  def up
    add_index :seo_keywords, :category
    add_index :seo_keywords, :keyword
  end

迁移将索引添加到表中,如架构所示:

  add_index "seo_keywords", ["category"], :name => "index_seo_keywords_on_category"
  add_index "seo_keywords", ["keyword"], :name => "index_seo_keywords_on_keyword"

我重新启动了服务器,加载了页面并得到了同样的错误。我想我创建的索引不正确?

谢谢你的帮助。

4

1 回答 1

1

在某些情况下(并且毫无疑问仅在某些 RDBMS 中),对于某些目的,使用索引执行排序而不是在查询执行中将记录排序为单独的步骤会更有效。

这样做的主要优点是它可以更快地为大型数据集带回第一行。

但是,它的缺点是在某些字符排序情况下需要语言排序索引,并且在访问数据方面通常效率较低,因此要返回的最后一行可能稍后会通过索引辅助排序返回。

此外,如果您要访问只有少量行的表的每一行(并且它们不会分散在一个大部分是空白空间的表中),那么全扫描表通常同样有效,而不是使用甚至唯一索引。

这些细微之处很难考虑,几乎所有数据库外部的方法都试图提供 100% 完整的“这就是你需要的索引”解决方案,在某种程度上都会存在缺陷,因此结果总是需要熟悉一些内部数据库知识。

在这种情况下(选择所有 64 行并按两列排序)可能会有所不同的是复合索引:

add_index "seo_keywords", ["category", "keyword"], :name => "index_seo_keywords_on_category_keyword"

但是,如果它们是字符串,则可能需要一个特殊的索引(恐怕我不是 mysql 专家)。

此外,根据 mysql 是否索引空值,您可能需要确保类别和/或关键字在数据库级别被限制为非空值。

于 2013-08-13T07:32:06.453 回答