MySQL Query太大了,有没有办法优化?

时间:2015-09-21 11:38:02

标签: mysql sql

有没有办法优化这个大型MySQL查询?我尝试了很多东西,但它们都给了我不正确的结果,例如重复和空列。

SELECT quotations.*, 

GROUP_CONCAT(DISTINCT CONCAT(groups.group_id, " | ", groups.group_name) SEPARATOR " , ") AS `quotation_groups`,
GROUP_CONCAT(DISTINCT CONCAT(departments.department_id, " | ", departments.department_name, " | ", departments.department_code) SEPARATOR " , ") AS `quotation_departments`,
GROUP_CONCAT(DISTINCT CONCAT(projects.project_id) SEPARATOR " , ") AS `quotation_projects`,
GROUP_CONCAT(DISTINCT CONCAT(machines.machine_id, " | ", machines.machine_name) SEPARATOR " , ") AS `quotation_machines`,
GROUP_CONCAT(DISTINCT CONCAT(parts.part_id, " | ", parts.part_name) SEPARATOR " , ") AS `quotation_parts`,
GROUP_CONCAT(DISTINCT CONCAT(options.option_id, " | ", options.option_name) SEPARATOR " , ") AS `quotation_options`,
GROUP_CONCAT(DISTINCT CONCAT(applications.application_id, " | ", applications.application_nl_title) SEPARATOR " , ") AS `quotation_applications`,
GROUP_CONCAT(DISTINCT CONCAT(actions.action_id, " | ", actions.action_name) SEPARATOR " , ") AS `quotation_actions`,
GROUP_CONCAT(DISTINCT CONCAT(tests.test_id, " | ", tests.test_name) SEPARATOR " , ") AS `quotation_tests`,
GROUP_CONCAT(DISTINCT CONCAT(notes.note_id, " | ", notes.note_name) SEPARATOR " , ") AS `quotation_notes`,
GROUP_CONCAT(DISTINCT CONCAT(companies.company_id, " | ", companies.company_name) SEPARATOR " , ") AS `quotation_companies`,
GROUP_CONCAT(DISTINCT CONCAT(persons.person_id, " | ", persons.person_gender, " | ", persons.person_firstname, " | ", persons.person_middlename, " | ", persons.person_lastname, " | ", persons.person_function) SEPARATOR " , ") AS `quotation_persons`,
GROUP_CONCAT(DISTINCT CONCAT(addresses.address_id, " | ", addresses.address_types, " | ", addresses.address_name, " | ", addresses.address_streetname, " | ", addresses.address_housenumber, " | ", addresses.address_zipcode, " | ", addresses.address_city) SEPARATOR " , ") AS `quotation_addresses`,
GROUP_CONCAT(DISTINCT CONCAT(attachments.attachment_id, " | ", attachments.attachment_name) SEPARATOR " , ") AS `quotation_attachments` 

FROM quotations quotations 

LEFT JOIN quotations_relations quotation_departments ON (quotation_departments.quotations_relations_child_name="departments" AND quotation_departments.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_groups ON (quotation_groups.quotations_relations_child_name="groups" AND quotation_groups.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_projects ON (quotation_projects.quotations_relations_child_name="projects" AND quotation_projects.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_machines ON (quotation_machines.quotations_relations_child_name="machines" AND quotation_machines.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_parts ON (quotation_parts.quotations_relations_child_name="parts" AND quotation_parts.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_options ON (quotation_options.quotations_relations_child_name="options" AND quotation_options.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_applications ON (quotation_applications.quotations_relations_child_name="applications" AND quotation_applications.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_actions ON (quotation_actions.quotations_relations_child_name="actions" AND quotation_actions.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_tests ON (quotation_tests.quotations_relations_child_name="tests" AND quotation_tests.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_notes ON (quotation_notes.quotations_relations_child_name="notes" AND quotation_notes.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_companies ON (quotation_companies.quotations_relations_child_name="companies" AND quotation_companies.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_persons ON (quotation_persons.quotations_relations_child_name="persons" AND quotation_persons.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_addresses ON (quotation_addresses.quotations_relations_child_name="addresses" AND quotation_addresses.quotations_relations_parent=quotations.quotation_id)
LEFT JOIN quotations_relations quotation_attachments ON (quotation_attachments.quotations_relations_child_name="attachments" AND quotation_attachments.quotations_relations_parent=quotations.quotation_id) 

LEFT JOIN groups_relations groups_relations ON (groups_relations.groups_relations_child_name="quotations" AND groups_relations.groups_relations_child_id=quotations.quotation_id) 
LEFT JOIN groups groups ON (groups.group_id=groups_relations.groups_relations_parent OR groups.group_id=quotation_groups.quotations_relations_child_id)
LEFT JOIN departments_relations departments_relations ON (departments_relations.departments_relations_child_name="quotations" AND departments_relations.departments_relations_child_id=quotations.quotation_id) 
LEFT JOIN departments departments ON (departments.department_id=departments_relations.departments_relations_parent OR departments.department_id=quotation_departments.quotations_relations_child_id)
LEFT JOIN projects_relations projects_relations ON (projects_relations.projects_relations_child_name="quotations" AND projects_relations.projects_relations_child_id=quotations.quotation_id) 
LEFT JOIN projects projects ON (projects.project_id=projects_relations.projects_relations_parent OR projects.project_id=quotation_projects.quotations_relations_child_id)
LEFT JOIN machines_relations machines_relations ON (machines_relations.machines_relations_child_name="quotations" AND machines_relations.machines_relations_child_id=quotations.quotation_id) 
LEFT JOIN machines machines ON (machines.machine_id=machines_relations.machines_relations_parent OR machines.machine_id=quotation_machines.quotations_relations_child_id)
LEFT JOIN parts_relations parts_relations ON (parts_relations.parts_relations_child_name="quotations" AND parts_relations.parts_relations_child_id=quotations.quotation_id) 
LEFT JOIN parts parts ON (parts.part_id=parts_relations.parts_relations_parent OR parts.part_id=quotation_parts.quotations_relations_child_id)
LEFT JOIN options_relations options_relations ON (options_relations.options_relations_child_name="quotations" AND options_relations.options_relations_child_id=quotations.quotation_id) 
LEFT JOIN options options ON (options.option_id=options_relations.options_relations_parent OR options.option_id=quotation_options.quotations_relations_child_id)
LEFT JOIN applications_relations applications_relations ON (applications_relations.applications_relations_child_name="quotations" AND applications_relations.applications_relations_child_id=quotations.quotation_id) 
LEFT JOIN applications applications ON (applications.application_id=applications_relations.applications_relations_parent OR applications.application_id=quotation_applications.quotations_relations_child_id)
LEFT JOIN actions_relations actions_relations ON (actions_relations.actions_relations_child_name="quotations" AND actions_relations.actions_relations_child_id=quotations.quotation_id) 
LEFT JOIN actions actions ON (actions.action_id=actions_relations.actions_relations_parent OR actions.action_id=quotation_actions.quotations_relations_child_id)
LEFT JOIN tests_relations tests_relations ON (tests_relations.tests_relations_child_name="quotations" AND tests_relations.tests_relations_child_id=quotations.quotation_id) 
LEFT JOIN tests tests ON (tests.test_id=tests_relations.tests_relations_parent OR tests.test_id=quotation_tests.quotations_relations_child_id)
LEFT JOIN notes_relations notes_relations ON (notes_relations.notes_relations_child_name="quotations" AND notes_relations.notes_relations_child_id=quotations.quotation_id) 
LEFT JOIN notes notes ON (notes.note_id=notes_relations.notes_relations_parent OR notes.note_id=quotation_notes.quotations_relations_child_id)
LEFT JOIN companies_relations companies_relations ON (companies_relations.companies_relations_child_name="quotations" AND companies_relations.companies_relations_child_id=quotations.quotation_id) 
LEFT JOIN companies companies ON (companies.company_id=companies_relations.companies_relations_parent OR companies.company_id=quotation_companies.quotations_relations_child_id)
LEFT JOIN persons_relations persons_relations ON (persons_relations.persons_relations_child_name="quotations" AND persons_relations.persons_relations_child_id=quotations.quotation_id) 
LEFT JOIN persons persons ON (persons.person_id=persons_relations.persons_relations_parent OR persons.person_id=quotation_persons.quotations_relations_child_id)
LEFT JOIN addresses_relations addresses_relations ON (addresses_relations.addresses_relations_child_name="quotations" AND addresses_relations.addresses_relations_child_id=quotations.quotation_id) 
LEFT JOIN addresses addresses ON (addresses.address_id=addresses_relations.addresses_relations_parent OR addresses.address_id=quotation_addresses.quotations_relations_child_id)
LEFT JOIN attachments_relations attachments_relations ON (attachments_relations.attachments_relations_child_name="quotations" AND attachments_relations.attachments_relations_child_id=quotations.quotation_id) 
LEFT JOIN attachments attachments ON (attachments.attachment_id=attachments_relations.attachments_relations_parent OR attachments.attachment_id=quotation_attachments.quotations_relations_child_id) 

GROUP BY quotations.quotation_id ORDER BY quotations.quotation_updated DESC

正如您所看到的,我需要从每个表格中获取与彼此有关系的所有细节。

我注意到,经过一段时间后,关系越多,查询越慢,例如,我有103个关系的引用,收集所有数据需要34秒。

2 个答案:

答案 0 :(得分:1)

我的第一个建议是使用条件聚合执行单个join。您可能不再需要DISTINCT中的GROUP_CONCAT()。这是部门的一个例子:

SELECT q.*,
       GROUP_CONCAT(CASE WHEN qr.quotations_relations_child_name = 'departments' THEN qr.department_id, ' | ', qr.department_name END)
FROM quotations q LEFT JOIN
     quotations_relations qr
     ON qr.quotations_relations_parent = q.quotation_id
GROUP BY q.quotation_id
ORDER BY q.quotation_updated DESC ;

答案 1 :(得分:0)

首先,您只能使用一个联接来引用:

LEFT JOIN quotations_relations ON quotations_relations_parent=quotations.quotation_id

并对各行进行关系检查: e.g。

LEFT JOIN groups groups ON 
(
groups.group_id=groups_relations.groups_relations_parent OR 
(groups.group_id=quotations_relations.quotations_relations_child_id AND quotations_relations_child_name="groups")
)