1

何かを行うためのより良い方法が常にあることは知っていますが、どうすればよいかわかりませんか? このクエリを最適化する最善の方法は何ですか? Joins、別のクエリなどを使用する必要があります.複雑なクエリではないことはわかっています..知識を広げようとしています。

任意の提案をいただければ幸いです!

SELECT
  community_threads.id AS thread_id,
  community_threads.title AS thread_title,
  community_threads.date AS thread_date,
  community_threads.author_id AS author_id,
  `user`.display_name AS author_name,
  `user`.organization AS author_organization,
  (SELECT date FROM community_replies replies WHERE replies.thread_id = community_threads.id ORDER BY date DESC LIMIT 1) AS reply_date,
  (SELECT   count(id) FROM community_replies replies WHERE replies.thread_id = community_threads.id ORDER BY date DESC LIMIT 1) AS total_replies
FROM
  community_threads
INNER JOIN `user` ON community_threads.author_id = `user`.id
WHERE
  category_id = '1'
ORDER BY
  reply_date DESC
LIMIT 0, 5
4

2 に答える 2

1

JOINこれは、集計COUNT()perthread_idと集計を取得する副選択に対して改善できますMAX(date)。行ごとに副選択を評価する代わりに、派生テーブルをクエリ全体に対して 1 回だけ評価し、残りの行に対して結合する必要がありますcommunity_threads

SELECT
  community_threads.id AS thread_id,
  community_threads.title AS thread_title,
  community_threads.date AS thread_date,
  community_threads.author_id AS author_id,
  `user`.display_name AS author_name,
  `user`.organization AS author_organization,
  /* From the joined subqueries */
  maxdate.date AS reply_date,
  threadcount.num AS total_replies
FROM
  community_threads
  INNER JOIN `user` ON community_threads.author_id = `user`.id
  /* JOIN against subqueries to return MAX(date) (same as order by date DESC limit 1) and COUNT(*) from replies */
  /* number of replies per thread_id */
  INNER JOIN  (
    SELECT thread_id, COUNT(*) AS num FROM replies GROUP BY thread_id
  ) threadcount ON community_threads.id = threadcount.thread_id
  /* Most recent date per thread_id */
  INNER JOIN (
    SELECT thread_id, MAX(date) AS date FROM replies GROUP BY thread_id
  ) maxdate ON community_threads.id = maxdate.thread_id
WHERE
  category_id = '1'
ORDER BY
  reply_date DESC
LIMIT 0, 5

サブクエリLIMIT 0, 5内に配置すると、さらにパフォーマンスが向上する場合があります。reply_dateこれにより、サブクエリで最新の 5 つだけが取得され、一致INNER JOINしないものはすべて破棄されます。community_threads

/* I *think* this will work...*/
SELECT
  community_threads.id AS thread_id,
  community_threads.title AS thread_title,
  community_threads.date AS thread_date,
  community_threads.author_id AS author_id,
  `user`.display_name AS author_name,
  `user`.organization AS author_organization,
  /* From the joined subqueries */
  maxdate.date AS reply_date,
  threadcount.num AS total_replies
FROM
  community_threads
  INNER JOIN `user` ON community_threads.author_id = `user`.id
  INNER JOIN  (
    SELECT thread_id, COUNT(*) AS num FROM replies GROUP BY thread_id
  ) threadcount ON community_threads.id = threadcount.thread_id
  /* LIMIT in this subquery */
  INNER JOIN (
    SELECT thread_id, MAX(date) AS date FROM replies GROUP BY thread_id ORDER BY date DESC LIMIT 0, 5
  ) maxdate ON community_threads.id = maxdate.thread_id
WHERE
  category_id = '1'
ORDER BY
  reply_date DESC
于 2012-10-11T19:35:27.983 に答える
0

私が知る限り、これはグループ化の良い機会のようです。

SELECT 
    community_threads.id AS thread_id,
    community_threads.title AS thread_title,
    community_threads.date AS thread_date,
    community_threads.author_id AS author_id,
    `user`.display_name AS author_name,
    `user`.organization AS author_organization,
    MAX(replies.date) AS reply_date,
    COUNT(replies.id) AS total_replies
FROM community_threads
INNER JOIN `user` ON community_threads.author_id = `user`.id
INNER JOIN community_replies AS replies ON replies.thread_id = community_threads.id
WHERE category_id = 1
GROUP BY thread_id, thread_title, thread_date, author_id, author_name, author_organization)
ORDER BY reply_date DESC
LIMIT 0, 5

お役に立てれば。

于 2012-10-11T19:42:06.457 に答える