热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在RubyOnRails中使用内部联接为表创建postgres索引-CreatepostgresindexfortablewithinnerjoininRubyOnRails

IhaveanappbasedonRubyOnRails4.0.Ihavetwomodels:StoresandProducts.Thereareabout1.5

I have an app based on RubyOnRails 4.0. I have two models: Stores and Products. There are about 1.5 million products in the system making it quite slow if I do not use indices properly.

我有一个基于RubyOnRails 4.0的应用程序。我有两种型号:商店和产品。如果我没有正确使用指数,系统中大约有150万个产品使它变得非常慢。

Some basic info

一些基本信息

  • Store has_many Products
  • 商店has_many产品
  • Store.affiliate_type_id is used where 1=Affiliated 2=Not affiliated
  • 使用Store.affiliate_type_id,其中1 =附属2 =不附属
  • Products have attributes like "category_connection_id" (integer) and "is_available" (boolean)
  • 产品具有“category_connection_id”(整数)和“is_available”(布尔值)等属性

In FeededProduct model:

在FeededProduct模型中:

scope :affiliated, -> { joins(:store).where("stores.affiliate_type_id = 1") } 

This query takes about 500ms which basically interrupts the website:

此查询大约需要500毫秒,这基本上会中断网站:

FeededProduct.where(:is_available => true).affiliated.where(:category_connection_id => @feeded_product.category_connection_id)

Corresponding postgresql:

对应的postgresql:

FeededProduct Load (481.4ms)  SELECT "feeded_products".* FROM "feeded_products" INNER JOIN "stores" ON "stores"."id" = "feeded_products"."store_id" WHERE "feeded_products"."is_available" = 't' AND "feeded_products"."category_connection_id" = 345 AND (stores.affiliate_type_id = 1)
Update. Postgresql EXPLAIN:
                                           QUERY PLAN
-------------------------------------------------------------------------------------------------
 Hash Join  (cost=477.63..49176.17 rows=21240 width=1084)
   Hash Cond: (feeded_products.store_id = stores.id)
   ->  Bitmap Heap Scan on feeded_products  (cost=377.17..48983.06 rows=38580 width=1084)
         Recheck Cond: (category_connection_id = 5923)
         Filter: is_available
         ->  Bitmap Index Scan on cc_w_store_index_on_fp  (cost=0.00..375.25 rows=38580 width=0)
               Index Cond: ((category_connection_id = 5923) AND (is_available = true))
   ->  Hash  (cost=98.87..98.87 rows=452 width=4)
         ->  Seq Scan on stores  (cost=0.00..98.87 rows=452 width=4)
               Filter: (affiliate_type_id = 1)
(10 rows)

Question: How can I create an index that will take the inner join into consideration and make this faster?

问题:如何创建一个将内部联接考虑在内并使其更快的索引?

1 个解决方案

#1


1  

That depends on the join algorithm that PostgreSQL chooses. Use EXPLAIN on the query to see how PostgreSQL processes the query.

这取决于PostgreSQL选择的连接算法。在查询上使用EXPLAIN来查看PostgreSQL如何处理查询。

These are the answers depending on the join algorithm:

这些是取决于连接算法的答案:

  1. nested loop join

    嵌套循环连接

    Here you should create an index on the join condition for the inner relation (the bottom table in the EXPLAIN output). You may further improve things by adding columns that appear in the WHERE clause and significantly improve selectivity (i.e., significantly reduce the number of rows filtered out during the index scan.
    For the outer relation, an index on the columns that appear in the WHERE clause will speed up the query if these conditions filter out most of the rows in the table.

    在这里,您应该为内部关系(EXPLAIN输出中的底部表)的连接条件创建索引。您可以通过添加WHERE子句中出现的列来进一步改进,并显着提高选择性(即,显着减少索引扫描期间过滤掉的行数。对于外部关系,WHERE子句中出现的列的索引如果这些条件过滤掉表中的大多数行,将加快查询速度。

  2. hash join

    散列连接

    Here it helps to have indexes on both tables on those columns in the WHERE clause where the conditions filter out most of the rows in the table.

    这里有条件在WHERE子句中的那些列上的两个表上有索引,其中条件过滤掉表中的大多数行。

  3. merge join

    合并加入

    Here you need indexes on the columns in the merge condition to allow PostgreSQL to use an index scan for sorting. Additionally, you can append columns that appear in the WHERE clause.

    在这里,您需要合并条件中的列的索引,以允许PostgreSQL使用索引扫描进行排序。此外,您可以追加WHERE子句中出现的列。

Always test with EXPLAIN if your indexes get used. If not, odds are that either they cannot be used or that using them would make the query slower than a sequential scan, e.g. because they do not filter out enough rows.

如果使用索引,请始终使用EXPLAIN进行测试。如果不是,则可能是它们不能被使用或者使用它们会使查询比顺序扫描更慢,例如,因为他们没有过滤掉足够的行。


推荐阅读
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了如何在Mac上使用Pillow库加载不同于默认字体和大小的字体,并提供了一个简单的示例代码。通过该示例,读者可以了解如何在Python中使用Pillow库来写入不同字体的文本。同时,本文也解决了在Mac上使用Pillow库加载字体时可能遇到的问题。读者可以根据本文提供的示例代码,轻松实现在Mac上使用Pillow库加载不同字体的功能。 ... [详细]
author-avatar
佳蓁政睿9
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有