优化具有连接的 MySQL 查询
Posted
技术标签:
【中文标题】优化具有连接的 MySQL 查询【英文标题】:Optimise MySQL query having joins 【发布时间】:2019-08-08 11:08:24 【问题描述】:如何优化下面的查询。因为它有太多的连接
SELECT `providers`.`provider_id`, `providers`.`providerFirstName`, `providers`.`providerLastName`, `providers`.`email`, `providers`.`phoneNumber`, `providers`.`address`, `providers`.`agencyName`, `providers`.`practiceCounty`, `providers`.`city`, `providers`.`state`, `providers`.`zip`, `providers`.`mondayHours`, `providers`.`tuesdayHours`, `providers`.`wednesdayHours`, `providers`.`thursdayHours`, `providers`.`fridayHours`, `providers`.`saturdayHours`, `providers`.`sundayHours`, `providers`.`additionalInfo`, `providers`.`website`, `providers`.`newClientsAcceptance`, `providers`.`updatedBy`, `providers`.`otherCategories`, `providers`.`otherInsurances`, `providers`.`otherTelehealthServices`, `providers`.`createdAt`, `providers`.`updatedAt`, `ProviderInsurances`.`provider_insurance_id` AS `ProviderInsurances.provider_insurance_id`, `ProviderInsurances`.`insurance_id` AS `ProviderInsurances.insurance_id`, `ProviderInsurances->Insurance`.`insurance_id` AS `ProviderInsurances.Insurance.insurance_id`, `ProviderInsurances->Insurance`.`insurance_name` AS `ProviderInsurances.Insurance.insurance_name`, `ProviderClients`.`provider_client_id` AS `ProviderClients.provider_client_id`, `ProviderClients`.`client_id` AS `ProviderClients.client_id`, `ProviderClients->Client`.`client_id` AS `ProviderClients.Client.client_id`, `ProviderClients->Client`.`client_name` AS `ProviderClients.Client.client_name`, `ProviderCounties`.`provider_county_id` AS `ProviderCounties.provider_county_id`, `ProviderCounties`.`county_id` AS `ProviderCounties.county_id`, `ProviderCounties->County`.`county_id` AS `ProviderCounties.County.county_id`, `ProviderCounties->County`.`county_name` AS `ProviderCounties.County.county_name`, `ProviderSpecialities`.`provider_speciality_id` AS `ProviderSpecialities.provider_speciality_id`, `ProviderSpecialities`.`speciality_id` AS `ProviderSpecialities.speciality_id`, `ProviderSpecialities->Speciality`.`speciality_id` AS `ProviderSpecialities.Speciality.speciality_id`, `ProviderSpecialities->Speciality`.`speciality_name` AS `ProviderSpecialities.Speciality.speciality_name`, `ProviderCategories`.`provider_category_id` AS `ProviderCategories.provider_category_id`, `ProviderCategories`.`category_id` AS `ProviderCategories.category_id`, `ProviderCategories->Category`.`category_id` AS `ProviderCategories.Category.category_id`, `ProviderCategories->Category`.`category_name` AS `ProviderCategories.Category.category_name`, `Telehealths`.`telehealth_id` AS `Telehealths.telehealth_id`, `Telehealths`.`telehealth_name` AS `Telehealths.telehealth_name`
FROM `providers` AS `providers`
LEFT OUTER JOIN `provider_insurances` AS `ProviderInsurances` ON `providers`.`provider_id` = `ProviderInsurances`.`provider_id`
LEFT OUTER JOIN `insurance` AS `ProviderInsurances->Insurance` ON `ProviderInsurances`.`insurance_id` = `ProviderInsurances->Insurance`.`insurance_id`
LEFT OUTER JOIN `provider_clients` AS `ProviderClients` ON `providers`.`provider_id` = `ProviderClients`.`provider_id`
LEFT OUTER JOIN `clients` AS `ProviderClients->Client` ON `ProviderClients`.`client_id` = `ProviderClients->Client`.`client_id`
LEFT OUTER JOIN `provider_counties` AS `ProviderCounties` ON `providers`.`provider_id` = `ProviderCounties`.`provider_id`
LEFT OUTER JOIN `counties` AS `ProviderCounties->County` ON `ProviderCounties`.`county_id` = `ProviderCounties->County`.`county_id`
LEFT OUTER JOIN `provider_specialities` AS `ProviderSpecialities` ON `providers`.`provider_id` = `ProviderSpecialities`.`provider_id`
LEFT OUTER JOIN `specialities` AS `ProviderSpecialities->Speciality` ON `ProviderSpecialities`.`speciality_id` = `ProviderSpecialities->Speciality`.`speciality_id`
LEFT OUTER JOIN `provider_categories` AS `ProviderCategories` ON `providers`.`provider_id` = `ProviderCategories`.`provider_id`
LEFT OUTER JOIN `categories` AS `ProviderCategories->Category` ON `ProviderCategories`.`category_id` = `ProviderCategories->Category`.`category_id`
LEFT OUTER JOIN `telehealth` AS `Telehealths` ON `providers`.`provider_id` = `Telehealths`.`provider_id`
WHERE `providers`.`updatedAt`
BETWEEN '2019-08-06 18:30:00' AND '2019-08-08 00:00:00';
减少执行时间的最佳做法是什么。请帮忙。
我在下面添加了“EXPLAIN SELECT”输出
【问题讨论】:
请提供EXPLAIN SELECT ...
@RickJames 我已经添加了上面的截图
请不要对EXPLAIN
的行进行排序;行的顺序是关键信息。
请提供SHOW CREATE TABLE provider_counties
【参考方案1】:
确保您对连接所涉及的列有正确的索引,例如:
为
table provider_insurances columns (provider_id, insurance_id)
table insurance columns (insurance_id)
table provider_clients columns (provider_id)
...
....
table providers columns (updatedAt, provider_id )
【讨论】:
是的,我已经为 updatedAt 添加了普通索引,并为上面所有剩余的列添加了主键索引。但执行时间仍然相同 还有另一列不仅涉及主键..所以检查你是否有建议的索引.. @rjirji 为了澄清 scaisEdge 已经发布的答案,您有 11 个外连接指定要连接的列(ONproviders
.provider_id
= ProviderInsurances
.provider_id
)。您必须确保这 22 列中的每一列都已编入索引。此外,应为 Where 子句中的所有列编制索引以获得更好的性能。
@James 主键是索引吗?所有 22 列都被赋予主键,where 子句中的列被赋予自定义索引。够了吗?
@rjirji - 是的 PRIMARY KEY
在索引中。 (它是一个UNIQUE
索引。)【参考方案2】:
您可以使用 sequelize ORM 来处理您的查询连接。链接 => [https://sequelize.org/master/manual/querying.html]
【讨论】:
不是续集。我在问如何优化执行时间 这不是答案。以上是关于优化具有连接的 MySQL 查询的主要内容,如果未能解决你的问题,请参考以下文章