以下のMySQLクエリを使用して、イベントリストページのイベントを取得しています。問題は、制限10で実行するのに約35秒かかります。ページング用にCOUNTを実行するにはもう35秒かかります。 ページの読み込み時間が70秒以上になると、想像できるように、がカットされません。そして、これは740イベントの結果だけです!私は2000+以上になるとこれがどのように動くか考えるのは怖いです。複雑なマルチジョインズMySQLクエリの高速化(問題がある場合はCakePHP経由で作成されます)
私たちは索引付けを試みましたが(索引知識が欠けていない限り)、それは文字どおり効果がありませんでした。
テーブルアソシエーションの説明: イベントは、レストランまたは会場で開催することができます。そのイベントの都市は、開催されているレストランまたは会場のcity_idによって決定されます。また、アップロード(この場合は写真)も取得しています。
多少混乱する部分はスケジュール/日付です - スケジュールはイベントの開始/終了/繰り返し情報を保持します。日付のレコードはスケジュールの情報に基づいて作成され、イベントが開催されている毎日の個々のレコードを保持します(start = datetime、end = datetime)
私はこのクエリを作成するためにCakePHPを使用しています。底部のアソシエーション:
SELECT
`Event`.*, `Venue`.`id`, `Venue`.`slug`, `Venue`.`name`, `Venue`.`GPS_Lon`,
`Venue`.`GPS_Lat`, `Venue`.`city_id`, `VenueCity`.`name`, `VenueCity`.`slug`,
`Restaurant`.`id`, `Restaurant`.`slug`, `Restaurant`.`name`, `Restaurant`.`GPS_Lat`,
`Restaurant`.`GPS_Lon`, `Restaurant`.`city_id`, `RestaurantCity`.`name`,
`RestaurantCity`.`slug`, GROUP_CONCAT(Date.start, "|", Date.end
ORDER BY Date.start ASC SEPARATOR "||") AS EventDates
FROM `events` AS `Event`
LEFT JOIN restaurants AS `Restaurant` ON (`Restaurant`.`id` = `Event`.`restaurant_id`)
LEFT JOIN venues AS `Venue` ON (`Venue`.`id` = `Event`.`venue_id`)
LEFT JOIN cities AS `VenueCity` ON (`Venue`.`city_id` = `VenueCity`.`id`)
LEFT JOIN cities AS `RestaurantCity` ON (`Restaurant`.`city_id` = `RestaurantCity`.`id`)
INNER JOIN schedules AS `Schedule` ON (`Schedule`.`event_id` = `Event`.`id`)
INNER JOIN dates AS `Date` ON (`Date`.`schedule_id` = `Schedule`.`id`)
LEFT JOIN uploads AS `Upload` ON (`Upload`.`event_id` = `Event`.`id`)
WHERE `Event`.`approval_status_id` = 1 AND `Date`.`start` >= '2011-07-11 12:38:54'
GROUP BY `Event`.`id`
ORDER BY `Date`.`start` ASC LIMIT 10
CakePHPのアソシエーション:
Event belongsTo Venue
Venue hasMany Event
Event belongsTo Restaurant
Restaurant hasmany Event
Event hasMany Upload
Upload belongsTo Event
City hasMany Restaurant
City hasMany Venue
Restaurant belongsTo City
Venue belongsTo City
Event hasMany Schedule
Schedule belongsTo Event
Schedule hasMany Date
Date belongsTo Schedule
UPDATE(@Zoredacheリクエストあたり):
これは私が選択する前にEXPLAIN追加することから得るものです:インデックスが正しいと仮定すると、
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Event ref PRIMARY,approval status approval status 5 const 946 Using where; Using temporary; Using filesort
1 SIMPLE Restaurant ref PRIMARY,id id 4 medut_ent.Event.restaurant_id 1
1 SIMPLE Venue ref PRIMARY,id id 4 medut_ent.Event.venue_id 1
1 SIMPLE VenueCity ref PRIMARY,id id 4 medut_ent.Venue.city_id 1
1 SIMPLE RestaurantCity ref PRIMARY,id id 4 medut_ent.Restaurant.city_id 1
1 SIMPLE Schedule ref PRIMARY,index index 5 medut_ent.Event.id 1 Using where; Using index
1 SIMPLE Date ref all cols,start... all cols 5 medut_ent.Schedule.id 8 Using where; Using index
1 SIMPLE Upload ALL 4240
説明を使って手動でクエリを実行しようとしましたか?重要なフィールドにインデックスを設定していますか? – Zoredache
@ Zoredache - 私は必要と思ったすべてのフィールドのインデックスを作成しようとしました。 EXPLAINを実行しました - 結果をUPDATEに投稿します。 – Dave
@Zoredache - 申し訳ありません - 読みやすくするためにフォーマットするのに少し時間がかかりました。 – Dave