ActiveRecord中多列的索引

col*_*rco 45 sql indexing activerecord ruby-on-rails

在ActiveRecord中,有两种方法可以为多列声明索引:

add_index :classifications, [:species, :family, :trivial_names]
add_index :classifications, :species
add_index :classifications, :family
add_index :classifications, :trivial_names

第一种方法和第二种方法之间有什么区别吗?如果是这样,我何时应该使用第一个和第二个?

Mar*_*ham 89

您正在将复合索引与一组独立索引进行比较.他们只是不同.

可以这样想:复合索引可让您快速查找嵌套字段集中的第一个字段,然后快速查找第二个字段,仅查看第一个字段已选择的记录,然后快速查看第三个字段的特写 - 再次,仅在前两个索引选择的记录中.

让我们举个例子.如果使用索引,数据库引擎将花费不超过20个步骤来查找1,000,000条记录中的唯一值(如果内存服务).这是真的不管你是使用复合或和独立的指数-但只适用于第一个字段(在你的榜样"种"虽然我还以为你会希望家庭,种类,然后通用名称).

现在,假设第一个字段值有100,000个匹配记录.如果您只有单个索引,那么这些记录中的任何查找将需要100,000步:第一个索引检索的每个记录一个.这是因为不会使用第二个索引(在大多数数据库中 - 这有点简化)并且必须使用强力匹配.

如果您有一个复合索引,那么您的搜索速度会快得多,因为您的第二个字段搜索将第一组值中包含索引.在这种情况下,您需要不超过17个步骤才能在字段1的100,000次匹配中获得第2个匹配值(日志基数2为100,000).

因此:使用3个嵌套字段上的复合索引从1,000,000条记录的数据库中查找唯一记录所需的步骤,其中第一个检索100,000,第二个检索10,000 = 20 + 17 + 14 = 51步.

在相同条件下所需的步骤仅有独立指数= 20 + 100,000 + 10,000 = 110,020步.

差异很大,嗯?

现在,不要疯狂地将复合指数放在各处.首先,它们在插入和更新方面很昂贵.其次,如果您真正搜索嵌套数据,它们只会受到影响(换另一个例子,我在为给定日期范围内的客户端提取数据时使用它们).此外,如果您使用相对较小的数据集,它们是不值得的.

最后,检查数据库文档.数据库已在部署索引这些天,我上述不得持有的一些数据库101方案的能力(虽然我总是发展,如果它不只是让我知道我得到)变得十分复杂.

  • collimarco - 在您提供给Matt先生的示例中,独立索引将提供更好的性能,因为每个索引都将作为SQL执行计划的一部分独立使用.可以这样想:AND是组合的,或者是独立的.再举一个例子,如果你的where子句是"WHERE(Family = X AND Species = Y)OR(CommonName = Z)"那么你需要一个Family | Species的综合索引和一个CommonName的独立索引. (3认同)

Mik*_*use 10

这两种方法不同.第一个在三个属性上创建一个索引,第二个创建三个单属性索引.存储要求会有所不同,尽管没有分发,但不可能说哪个会更大.

当您需要访问A,A + B和A + B + C的值时,索引三列[A,B,C]可以很好地工作.如果您的查询(或查找条件或其他内容)未引用A,那将不会有任何好处.

当A,B和C分别编制索引时,一些DBMS查询优化器会考虑组合两个或多个索引(取决于优化程序的效率估计),以便为单个多列索引提供类似的结果.

假设你有一些电子商务系统.您想通过purchase_date,customer_id和有时两者查询订单.我首先创建两个索引:每个属性一个.

另一方面,如果您始终指定purchase_date customer_id,则两列上的单个索引可能最有效.订单很重要:如果您还想查询客户的所有日期的订单,请将customer_id作为索引中的第一列.