使用多个连接和Group_Concat优化php mySQL查询

时间:2013-07-21 23:12:43

标签: php mysql join group-concat

我的查询中发生了多个连接集。我有多个连接,因为表的结构方式可以得到我想要的东西。我的主要联接,我已分为三组,如下所述。如果我只有一组,查询时间非常快。当我有两个活动集时,查询时间约为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";

1 个答案:

答案 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()创建的列表中也有重复项。这种方法也可以解决这个问题。