我的查询中发生了多个连接集。我有多个连接,因为表的结构方式可以得到我想要的东西。我的主要联接,我已分为三组,如下所述。如果我只有一组,查询时间非常快。当我有两个活动集时,查询时间约为2分钟。如果所有三个组都处于活动状态,如下所示,则需要很长时间。
任何有关优化此查询的帮助都将不胜感激。
$query = "SELECT `Databases`.*,
`DatabaseDescriptors`.*,
`DatabaseContents`.*,
`DatabaseAccessLevels`.*,
`Providers`.*,
GROUP_CONCAT(`Descriptors`.DescriptorName SEPARATOR ', ') as DescriptorNames,
GROUP_CONCAT(`Contents`.ContentName SEPARATOR ', ') as ContentNames,
GROUP_CONCAT(`AccessLevels`.AccessLevelName SEPARATOR ', ') as AccessLevelNames ";
$query .= "FROM `Databases` ";
// SET 1
$query .= "JOIN `DatabaseDescriptors`
ON `DatabaseDescriptors`.DatabaseID = `Databases`.DatabaseID ";
$query .= "JOIN `Descriptors`
ON `Descriptors`.DescriptorID = `DatabaseDescriptors`.DescriptorID ";
//SET 2
$query .= "JOIN `DatabaseContents`
ON `DatabaseContents`.DatabaseID = `Databases`.DatabaseID ";
$query .= "JOIN `Contents`
ON `Contents`.ContentID = `DatabaseContents`.ContentID ";
//SET 3
$query .= "JOIN `DatabaseAccessLevels`
ON `DatabaseAccessLevels`.DatabaseID = `Databases`.DatabaseID ";
$query .= "JOIN `AccessLevels`
ON `AccessLevels`.AccessLevelID = `DatabaseAccessLevels`.AccessLevelID ";
$query .= "JOIN `Providers`
ON `Providers`.ProviderID = `Databases`.ProviderID ";
$query .= "AND `Databases`.DatabaseID = 47";
答案 0 :(得分:0)
性能问题的原因是数据库"有多个描述符,访问级别和内容。假设一个数据库有10个。查询最终将其转换为10 * 10 * 10 = 1000行进行处理。
解决方案是在进行连接之前进行聚合。例如,而不是:
$ query。="加入DatabaseDescriptors
ON DatabaseDescriptors
。DatabaseID = Databases
。DatabaseID&#34 ;;
$query .= "JOIN `Descriptors`
ON `Descriptors`.DescriptorID = `DatabaseDescriptors`.DescriptorID ";
你会:
(select dd.DatabaseId,
GROUP_CONCAT(d.DescriptorName SEPARATOR ', ') as DescriptorNames
from DatabaseDescriptors dd join
Descriptions d
on dd.DescriptorID = d.DescriptorID
group by dd.DatabaseId
) dd
on Databases.DatabaseId = dd.DatabaseId
(您可以将group by dd.DatabaseId
替换为where dd.DatabaseId = 47
来处理您的一个案例。我的猜测是您可能想要所有数据库的此信息。如果是这样,请添加group by DatabaseId
到外部查询。)
然后,您需要对所有三个group_concat()
列重复此操作。
注意:您将从所有表中提取所有字段。但是,由于您的聚合查询没有group by
,因此只返回一行。我猜你在group_concat()
创建的列表中也有重复项。这种方法也可以解决这个问题。