我有查詢,需要搜索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