我有查询,需要搜索3个表中的数据。Rails查询与包括需要很长的时间
公司表= 280K行
PostIndex表= 3.1k行
CompanyCategory = 5行
查询看起来是这样的:
query = ''
associations = [:post_index, :company_category]
Company.includes(associations).references(associations).where(query).order(:id).limit(25)
为了简化问题,让我们坐在这个查询是空字符串。另外我有相关记录的索引。
这个查询加载时间= 1.2-1.3秒,即使是空的条件。并且最多2秒钟不空查询。
如何加快此查询?
事件这个简单的查询需要250ms的加载: Company.find_by(name: 'asd')
是否elasticsearch(或类似)是在我的情况下,唯一的解决办法?
PS我不能使用内部连接,因为并不是所有的企业都post_index
感谢您的帮助提前
更新1
只是意识到上面的查询需要约1.3秒指定的顺序和6毫秒没有指定的顺序。即使我按索引列(例如'companies.id')排序,它仍然很慢,需要1.3秒。有什么建议么?
更新2
我试着做了解释疑问,这里是结果:
(http://i.stack.imgur.com/VzKE6.png)
我检查的模式,我有分类与PostIndices指标有:
add_index "companies", ["company_category_id"], name: "index_companies_on_company_category_id", using: :btree
add_index "companies", ["post_index_id"], name: "index_companies_on_post_index_id", using: :btree
(http://i.stack.imgur.com/eInwr.png)
对于这两个模型,与公司模型的关系完全相同。但相应的解释,它表现不同。我不熟悉EXPLAIN,但从我读过的内容 - 加入类别时,加入类型是ALL,这是不好的。它搜索138632 * 5行。
但是,当加入PostIndex时,加入类型是eq_ref,所以它搜索138632 * 1行。所以我完全困惑为什么会发生这种情况。任何想法?
UPDATE 4
SHOW CREATE TABLE公司;
(http://i.stack.imgur.com/E6CEO.png)
UPDATE 5
SLOW RUBY:
Company.includes(associations).references(associations).where(query).order(:id).limit(25).explain
SLOW SQL:
SELECT `companies`.`id` AS t0_r0, `companies`.`name` AS t0_r1,
`companies`.`address` AS t0_r2, `companies`.`post_index_id` AS t0_r3,
`companies`.`tel` AS t0_r4, `companies`.`mobile` AS t0_r5,
`companies`.`fax` AS t0_r6, `companies`.`email` AS t0_r7,
`companies`.`website` AS t0_r8, `companies`.`vat` AS t0_r9,
`companies`.`company_category_id` AS t0_r10, `companies`.`nace` AS t0_r11,
`companies`.`union` AS t0_r12, `companies`.`note` AS t0_r13,
`companies`.`created_at` AS t0_r14, `companies`.`updated_at` AS t0_r15,
`companies`.`ean` AS t0_r16, `companies`.`deleted_at` AS t0_r17,
`companies`.`sector` AS t0_r18, `companies`.`status` AS t0_r19,
`post_indices`.`id` AS t1_r0, `post_indices`.`county` AS t1_r1,
`post_indices`.`postal_code` AS t1_r2, `post_indices`.`group_part` AS t1_r3,
`post_indices`.`group_number` AS t1_r4, `post_indices`.`group_name` AS t1_r5,
`post_indices`.`city` AS t1_r6, `post_indices`.`created_at` AS t1_r7,
`post_indices`.`updated_at` AS t1_r8,
-- EXTRA:
`company_categories`.`id` AS t2_r0,
`company_categories`.`name` AS t2_r1, `company_categories`.`created_at` AS t2_r2,
`company_categories`.`updated_at` AS t2_r3
-- END EXTRA
FROM `companies`
LEFT OUTER JOIN `post_indices` ON `post_indices`.`id` = `companies`.`post_index_id`
-- EXTRA:
LEFT OUTER JOIN `company_categories` ON `company_categories`.`id` = `companies`.`company_category_id`
-- END EXTRA
WHERE `companies`.`deleted_at` IS NULL
ORDER BY `companies`.`id` ASC
LIMIT 25
FAST RUBY:
Company.includes(associations.first).references(associations.first).where(query).order(:id).limit(25).explain
FAST SQL:
SELECT `companies`.`id` AS t0_r0, `companies`.`name` AS t0_r1,
`companies`.`address` AS t0_r2, `companies`.`post_index_id` AS t0_r3,
`companies`.`tel` AS t0_r4, `companies`.`mobile` AS t0_r5,
`companies`.`fax` AS t0_r6, `companies`.`email` AS t0_r7,
`companies`.`website` AS t0_r8, `companies`.`vat` AS t0_r9,
`companies`.`company_category_id` AS t0_r10, `companies`.`nace` AS t0_r11,
`companies`.`union` AS t0_r12, `companies`.`note` AS t0_r13,
`companies`.`created_at` AS t0_r14, `companies`.`updated_at` AS t0_r15,
`companies`.`ean` AS t0_r16, `companies`.`deleted_at` AS t0_r17,
`companies`.`sector` AS t0_r18, `companies`.`status` AS t0_r19,
`post_indices`.`id` AS t1_r0, `post_indices`.`county` AS t1_r1,
`post_indices`.`postal_code` AS t1_r2, `post_indices`.`group_part` AS t1_r3,
`post_indices`.`group_number` AS t1_r4, `post_indices`.`group_name` AS t1_r5,
`post_indices`.`city` AS t1_r6, `post_indices`.`created_at` AS t1_r7,
`post_indices`.`updated_at` AS t1_r8
FROM `companies`
LEFT OUTER JOIN `post_indices` ON `post_indices`.`id` = `companies`.`post_index_id`
WHERE `companies`.`deleted_at` IS NULL
ORDER BY `companies`.`id` ASC
LIMIT 25
更多细节在此要旨:
https://gist.github.com/vlad-ninja/1d6c77eeb0a328341640
(http://i.stack.imgur.com/NhpaX.png)
UPDATE 6
UPDATE 7
解释格式JSON要旨:
https://gist.github.com/vlad-ninja/b4a962aabe1a34ad773a
大概每个表都有一个索引的Id列。但是他们有一个外键列到索引的其他表吗?例如,'company.category_id'有一个索引?这应该使联接更快。 – Turophile
是的,我编入了'company.categrory_id'和其他foreign_keys。但我认为原因是因为加入类别。因为当我只加入PostIndex时,一切都很顺利和快速。请参阅更新2 – vladra