ActiveRecord中多列的索引

在ActiveRecord中有两种方法来为多个列声明索引:

  add_index:分类,[:species,:family,:trivial_names] 
  add_index:分类,:物种
 add_index:分类,:家庭
 add_index:分类,:trivial_names 

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

您正在比较一个复合指数和一组独立指数。 他们是不同的。

您可以这样想:复合索引可以快速查找嵌套字段集中的第一个字段 ,然后快速查找第一个字段已经select的logging中的第二个字段 ,然后快速查找第三个字段的第一个字段 – 只是在前两个索引select的logging中。

让我们举个例子。 如果您正在使用索引, 您的数据库引擎只需要20个步骤即可在1,000,000个logging(如果有内存服务)中查找唯一值。 无论您是使用复合索引还是独立索引,这都是事实 – 但只适用于第一个字段(在您的示例中为“物种”,尽pipe我认为您需要Family,Species和Common Name)。

现在,假设第一个字段值有100,000个匹配logging。 如果您只有单一索引,那么这些logging中的任何查找将执行100,000个步骤:第一个索引检索的每个logging都有一个。 这是因为第二个索引不会被使用(在大多数数据库中 – 这有点简化),必须使用powershell匹配。

如果你有一个复合索引,那么你的search速度要快得多,因为你的第二个字段search将第一组值中有一个索引。 在这种情况下,您将需要不超过17个步骤才能在字段1的100,000个匹配中的第2个字段上获得您的第一个匹配值(以10万为基数的第2个logging)。

因此:需要使用3个嵌套字段(其中第一个检索100,000个,第二个检索10,000 = 20 + 17 + 14 = 51个步骤)的复合索引,从包含1,000,000个logging的数据库中find唯一logging的步骤。

相同条件下需要的步骤,只有独立索引= 20 + 100,000 + 10,000 = 110,020步骤。

很大的区别,呃?

现在, 不要把复合指标放在任何地方。 首先,它们在插入和更新上花费很大。 其次,如果您真正在嵌套数据中进行search(例如,在为给定date范围内的客户端提供login数据时使用这些数据),它们才会受到影响。 而且,如果你使用的是相对较小的数据集,它们也是不值得的。

最后,检查你的数据库文档。 现在数据库在部署索引的能力方面已经变得非常复杂了,而且上面描述的数据库101场景可能不适用于某些(尽pipe我总是开发,就好像我知道我所得到的那样)。

这两种方法是不同的。 第一个创build三个属性的单个索引,第二个创build三个单一属性索引。 存储需求会有所不同,虽然没有分配,但是不可能说哪个会更大。

当您需要访问A,A + B和A + B + C的值时,对三列[A,B,C]进行索引时效果很好。 如果您的查询(或查找条件或其他)没有引用A将不会有任何好处。

当A,B和C被分别索引时,一些DBMS查询优化器会考虑组合两个或更多个索引(受优化器的效率估计),以给出与单个多列索引类似的结果。

假设你有一些电子商务系统。 您想通过purchase_date,customer_id和有时两个查询订单。 我开始创build两个索引:每个属性一个。

另一方面,如果您总是指定purchase_date customer_id,那么两列上的单个索引可能是最有效的。 订单是有意义的:如果您还想查询客户所有date的订单,请将customer_id设置为索引中的第一列。

从文档:

在多列上创build索引时,第一列用作索引的名称。 例如,当您在两列[:first,:last]上指定索引时,DBMS将为这两列创build一个索引,并为第一列创build一个索引:first。 为这个索引使用第一个名字是有道理的,因为你永远不需要用这个名字创build一个单独的索引。

在创build复合索引时使用第一种方法,在单个属性上创build索引时使用第一种方法。

关于何时使用复合索引有一些好的一点,但要点是,当利用多个属性的where时,它们是好的。 请注意,它们应该与其他索引一起使用(始终索引您的foriegn键) – 不能作为replace。