2

約 600 万行あるスター スキーマのファクト テーブル「foo_success」に対するクエリがあります。このテーブルは、ディメンション テーブルへの (整数) 参照のみを保持します。ストレージ エンジンとして MyISAM を使用します。

クエリ:

SELECT 
hierarchy.level0name,
hierarchy.level1name,
hierarchy.level0,
hierarchy.level1,
date.date,
address.city,
user.emailAddress,
foo_object.name,
foo_object.type,
user_group.groupId,
COUNT(user.id) AS count_user_id,
SUM(foo_object_statistic.passes) AS sum_foo_object_statistic_passes,
SUM(foo_object_statistic.starts) AS sum_foo_object_statistic_starts,
SUM(foo_object_statistic.calls) AS sum_foo_object_statistic_calls

FROM 
foo_success,
user,
user_group,
address, 
hierarchy,
foo_object,
foo_object_statistic,
date

WHERE (foo_success.userDimensionId = user.id)
AND (foo_success.userGroupDimensionId = user_group.id)
AND (foo_success.addressDimensionId = address.id)
AND (foo_success.hierarchyDimensionId = hierarchy.id)
AND (foo_success.fooObjectDimensionId = foo_object.id)
AND (foo_success.fooObjectStatisticDimensionId = foo_object_statistic.id)
AND (foo_success.dateDimensionId=date.id)
AND hierarchy.level0 = 'XYZ'
AND hierarchy.level1 IS NOT NULL 
AND hierarchy.level2 IS NOT NULL 
AND hierarchy.level3 IS NOT NULL 
AND hierarchy.level4 IS NOT NULL 
AND hierarchy.level5 IS NOT NULL 
AND hierarchy.level6 IS NULL 
AND hierarchy.level7 IS NULL
GROUP BY hierarchy.level0, foo_object.fooObjectId
LIMIT 0, 25;

私がこれまでに試したこと:

  • これは単純な結合バージョンであり、INNER JOIN の代替と同等の速度です。
  • 結合された、または条件の一部であるすべてのフィールドにインデックスがあります。
  • このクエリで EXPLAIN を使用したところ、クエリのコスト (処理された行数) は、テーブル user で 128596、テーブル foo_success で 77 であることがわかりました。
  • ユーザー テーブルへの依存関係を削除しようとしましたが、これにより、ファクト テーブル foo_success で 600 万を超える処理行数が発生しました。

このクエリを完了するのに約 1.5 分かかります。これは、読み取り速度が最適化されたデータ ウェアハウスのスター スキーマに対する私の期待をはるかに超えています。このモンスターを最適化する方法はありますか?

4

1 に答える 1

2

クエリの非効率性は、ほとんどの場合、実際には使用しない大量のデータを転送することに起因します。フィールドhierarchy.level1name, hierarchy.level0name, hierarchy.level1, date.date, address.city, user.emailAddress, foo_object.name, foo_object.type, user_group.groupIdは句に含まれていませんGROUP BY。つまり、情報は行ごとに取得され、メモリにロードされてから破棄されます。

私がお勧めするのは、すべての十分な ID と集計結果の取得をサブクエリに集中させてから、残りのテーブルに結合して、各結合で生成される行が 1 つだけになるようにすることです (LIMITサブクエリで句を移動することもできます)。必要な後続の JOIN 操作を最小限に抑えるため)。その後、有用なインデックスがないことに気付くかもしれません。

于 2013-02-05T08:51:07.363 に答える