我们有一个自行开发的文档管理系统,我们的系统运行非常慢,尤其是在搜索上。起初它运行良好,但是随着时间的推移,它变得越来越慢。现在,根据条件需要30到150秒才能返回结果。这是我们的搜索查询。我们一直在左右盯着这个东西,看不到任何地方可以对其进行进一步的调整。所有连接的字段都在其各自的表上建立索引。

SELECT DISTINCT f.*, ts.*, fo.*, ft.*, p.*, u.*, c.*, co.*, ct.*, fs.*, fd.*, r.*, rt.*, si.*, s.* FROM (
SELECT DISTINCT f.* FROM files f
JOIN folders fo ON(fo.id = f.belongs_to_folder_id)
JOIN projects p ON(p.id = f.belongs_to_project_id)
LEFT OUTER JOIN file_statuses fs ON(fs.id = f.file_status_id)
LEFT OUTER JOIN submittal_items_files sif ON(sif.file_id = f.id)
LEFT OUTER JOIN submittal_items si ON(si.id = sif.submittal_item_id)
LEFT OUTER JOIN submittals s ON(s.id = si.belongs_to_submittal_id)
LEFT OUTER JOIN record_types rt ON(rt.id = f.record_type_id)
LEFT OUTER JOIN companies co ON(co.id = f.company_id)
LEFT JOIN folders_actions_groups ag ON (
    f.belongs_to_folder_id = ag.folder_id AND
    ag.action_id = 10010
)
LEFT JOIN files_actions_groups fg ON (fg.file_id = f.id)
JOIN users_groups ug ON ((ug.group_id = ag.group_id OR ug.group_id = fg.group_id) AND ug.user_id = 411)
WHERE (
    (f.file_generated_name LIKE CONCAT('%', 'the', '%')) OR
    (f.record_id LIKE CONCAT('%', 'the', '%')) OR
    (f.record_title LIKE CONCAT('%', 'the', '%')) OR
    (f.additional_info LIKE CONCAT('%', 'the', '%')) OR
    (si.item_number LIKE CONCAT('%', 'the', '%')) OR
    (s.element_number LIKE CONCAT('%', 'the', '%'))
) AND f.path LIKE CONCAT('Some Text', '%') AND
f.file_status_id = 3 AND
f.file_revision = 1 AND
f.discipline_id = 1 AND
f.record_type_id = 2 AND
f.triage_status_id = 2 AND
f.deleted = 0
ORDER BY f.created DESC, f.id DESC
LIMIT 100
) AS f
LEFT OUTER JOIN users u ON(f.created_by_user_id = u.id)
LEFT OUTER JOIN contacts c ON(c.user_id = u.id)
LEFT OUTER JOIN companies co ON(co.id = f.company_id)
LEFT OUTER JOIN company_types ct ON(ct.id = co.company_type_id)
JOIN triage_statuses ts ON(f.triage_status_id = ts.id)
JOIN folders fo ON(fo.id = f.belongs_to_folder_id)
JOIN folder_types ft ON(ft.id = fo.folder_type_id)
JOIN projects p ON(p.id = f.belongs_to_project_id)
LEFT OUTER JOIN file_statuses fs ON(fs.id = f.file_status_id)
LEFT OUTER JOIN file_disciplines fd ON(fd.id = f.discipline_id)
LEFT OUTER JOIN revisions r ON(r.id = f.file_revision)
LEFT OUTER JOIN record_types rt ON(rt.id = f.record_type_id)
LEFT OUTER JOIN submittal_items_files sif ON(sif.file_id = f.id)
LEFT OUTER JOIN submittal_items si ON(si.id = sif.submittal_item_id)
LEFT OUTER JOIN submittals s ON(s.id = si.belongs_to_submittal_id)
LEFT OUTER JOIN files_actions_groups ffg ON(ffg.file_id = f.id)
LEFT OUTER JOIN groups g ON(g.id = ffg.group_id)
ORDER BY f.created DESC, f.id DESC

最佳答案

这可能是一个显而易见的答案,但是您是否已索引数据库?如果您不熟悉索引,这里有一个很好的规则:只需在所有名为“ id”的列(例如folder.id或projects.id)上放置唯一索引,然后在所有引用a的列上放置标准索引外部ID,例如folder.belongs_to_folder_id或folder.record_type_id

我要更改的另一件事是尝试仅选择您将实际使用的列,而不是您的f.*, ts.*, fo.*, ft.*, p.*, u.*, c.*, co.*, ct.*, fs.*, etc...庞大列表

您还拥有大量的连接,这在处理时间方面非常昂贵。您真的需要所有这些联接表吗?

10-06 14:19
查看更多