Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 695299
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T02:56:42+00:00 2026-05-14T02:56:42+00:00

Hi i’ve wrote a query that works: SELECT `comments`.* FROM `comments` RIGHT JOIN (SELECT

  • 0

Hi i’ve wrote a query that works:

SELECT `comments`.* FROM `comments` 
RIGHT JOIN (SELECT MAX( id ) AS id, core_id, topic_id 
FROM comments GROUP BY core_id, topic_id order by id desc) comm 
ON comm.id = comments.id LIMIT 10

I want know if it is possible (and how) to rewrite it to get better performance.

Thanks

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T02:56:42+00:00Added an answer on May 14, 2026 at 2:56 am

    Method 1 – improving the original query

    I am pretty sure that in this case is an INNER JOIN will suffice, there is no reason to do a RIGHT JOIN (if an id exists in comm it will also exists in comments). INNER JOINs can result in better performance.

    Moreover, you really want to push the LIMIT 10 inside comm (incidentally, keeping it together with the ORDER BY):

    • for one, not keeping LIMIT 10 and ORDER BY together will not get you the ten most recently posted-to topics (the ordering of the comm subquery will not necessarily be preserved into the final result which you are LIMITing.)
    • additionally, enforcing the LIMIT inside the innermost, aggregate subquery will encourage cost-based optimizers to favour nested loops (10, to be exact) over hash or merge joins (the 10 nested loops being by far the fastest for any respectably-sized comments table.)

    So, your query should be rewritten as:

    SELECT `comments`.* FROM `comments` 
    INNER JOIN (
     SELECT MAX( id ) AS id, core_id, topic_id 
     FROM comments
     GROUP BY core_id, topic_id
     ORDER BY id DESC
     LIMIT 10
    ) comm 
    ON comm.id = comments.id
    ORDER BY comments.id
    

    Finally, use EXPLAIN to see what the query is doing. Do not forget to check that you have created an index on comments.id to help with the JOIN nested loops.

    Method 2 – a different approach

    Note that while the above query could still be faster than your original query, the innermost comm subquery may still turn out to be a significant bottleneck if it results in a full table scan of comments. This really depends on how smart the database is when it sees GROUP BY, ORDER BY and LIMIT together.

    If EXPLAIN indicates that the subquery is doing a table scan, then you can try a combination of SQL and application-level logic to get the best performance assuming that I have understood your requirement correctly and that you want to identify the ten most recent comments posted in ten different topics:

    # pseudo-code
    core_topics_map = { }
    command = "SELECT * FROM comments ORDER BY id DESC;"
    command.execute
    # iterate over the result set, betting that we will be able to break
    #  early, bringing only a handful of rows over from the database server
    while command.fetch_next_row do
      # have we identified our 10 most recent topics?
      if core_topics_map.size >= 10 then
        command.close
        break
      else
        core_topic_key = pair(command.field('core_id'), command.field('topic_id'))
        if not defined?(core_topics_map[core_topic_key]) then
          core_topics_map[core_topic_key] = command.field('id')
        end
      end
    done
    # sort our 10 topics in reverse chronological order
    sort_by_values core_topics_map
    

    In most cases (that is, provided that your application’s database driver does not attempt to buffer all rows into memory for you before giving you back control from execute), the above will only fetch a handful of rows, always using an index, with no table scans involved.

    Method 3 – a hybrid approach

    If ten seconds ago I knew what the ten most recent comments were, can I be smart about it when I ask the question again later on? Unless comments can be deleted from the database, then the answer is yes, because I know that, when I ask the question again, all comment IDs will be greatly than or equal to the oldest comment ID I got in my last query.

    I can therefore rewrite the innermost query to be much, much more selective using an additional condition, WHERE id >= :last_lowest_id:

    SELECT `comments`.* FROM `comments` 
    INNER JOIN (
     SELECT MAX( id ) AS id, core_id, topic_id 
     FROM comments
     WHERE id >= :last_lowest_id
     GROUP BY core_id, topic_id
     ORDER BY id DESC
     LIMIT 10
    ) comm 
    ON comm.id = comments.id
    ORDER BY comments.id
    

    When you run the query for the very first time, use 0 for :last_lowest_id. The query will return up to 10 rows, in descending order. Inside your application, put aside the id of the last row, and reuse its value as :last_lowest_id the next time you run the query, and repeat (again, put aside the id of the last row returned by the latest query etc.) This will essentially make the query incremental, and extremely fast.

    Example:

    • running the query for the first time with :last_lowest_id set to 0
      • returns 10 rows with IDs: 129, 100, 99, 88, 83, 79, 78, 75, 73, 70
      • save 70
    • running the query for the second time with :last_lowest_id set to 70
      • returns 10 rows with IDs: 130, 129, 100, 99, 88, 83, 79, 78, 75, 73
      • save 73
    • etc.

    Method 4 – yet another approach

    If you expect to perform SELECT ... ORDER BY id DESC LIMIT 10 much more often than INSERTs into the comments table, consider putting a bit more work into the INSERT to make the SELECT faster. Thus, you can add an indexed updated_at column to your topics etc. table, and whenever you INSERT a comment into the comments table consider also updating the corresponding topic’s updated_at value to NOW(). You can then easily select the 10 most recently updated topics (a simple and short index scan on updated_at returning 10 rows), inner joining with the comments table to get the MAX(id) for those 10 topics (infinitely more efficient than getting MAX(id) for all topics before picking the ten greatest, like in the original and Method 1), then inner joining again on comments to get the rest of thecolumn values for those 10.

    I expect overall performance of Method 4 to be comparable with Methods 2 and 3. Method 4 will have to be used if you need to get arbitrary topics (e.g. by paginating them, LIMIT 10 OFFSET 50) or if topics or comments can be removed (no changes necessary to support topic removal; to support comment removal properly then the topic’s updated_at should be updated on both comment INSERT and DELETE with the created_at value of the latest non-deleted comment for the topic.)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
I have a French site that I want to parse, but am running into
link Im having trouble converting the html entites into html characters, (&# 8217;) i
Does anyone know how can I replace this 2 symbol below from the string
this is what i have right now Drawing an RSS feed into the php,
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a bunch of posts stored in text files formatted in yaml/textile (from
I want use html5's new tag to play a wav file (currently only supported

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.