0

クエリで複数の結合セットが発生しています。必要なものを取得するためにテーブルが構造化されているため、複数の結合があります。私の主な結合は、以下にコメントされているように 3 つのセットに分かれています。セットが 1 つしかない場合、クエリ時間はかなり高速です。2 つのセットをアクティブにすると、クエリ時間は約 2 分です。以下に示すように、3 つのセットすべてがアクティブな場合は、時間がかかりすぎます。

このクエリの最適化に関するヘルプをいただければ幸いです。

$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";
4

1 に答える 1

0

パフォーマンスの問題の理由は、「データベース」に複数の記述子、アクセス レベル、およびコンテンツがあるためです。データベースにそれぞれ 10 個あるとします。クエリは、これを処理のために 10*10*10 = 1000 行に変換します。

解決策は、結合を行う前に集計を行うことです。たとえば、これの代わりに: $query .= "JOIN DatabaseDescriptors ON DatabaseDescriptors.DatabaseID = Databases.DatabaseID ";

$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、1 つのケースだけを処理することができます。私の推測では、すべてのデータベースについてこの情報が必要になる可能性があります。その場合group by DatabaseIdは、外側のクエリに a を追加してください。)

group_concat()次に、3 つの列すべてに対してこれを繰り返す必要があります。

注: すべてのテーブルからすべてのフィールドを取得しています。ただし、 no を使用した集計クエリがあるため、返される行は 1 行のみですgroup by。で作成されたリストでも重複しているとgroup_concat()思います。このアプローチは、その問題も解決します。

于 2013-07-22T00:50:35.230 に答える