I need top 6 records of each subcategory from a mysql table having almost 100k records. I tried the following mysql query, but I'm concerned about its performance in my table having large number of records.
SELECT
*
FROM
(SELECT
sub_cat_id,
title,
@rn:=IF(@prev = sub_cat_id, @rn + 1, 1) AS rn,
@prev:=sub_cat_id AS previd,
created_date
FROM
blog
WHERE
type = 'BLOG'
AND FIND_IN_SET(sub_cat_id, '1,2,8')
AND created_date <= NOW()
ORDER BY sub_cat_id DESC , created_date DESC) AS records
WHERE
rn <= 6
In the above query, MySQL will number all the records having sub_cat_id 1,2 and 8. In the outer select query, the records will cut down to 6 records for each subcategory.
I'm having the following concerns
- Is this the better and fastest way to get 6 records for each subcategory
- Is this query generates desired result.
Here is my blog table
+-------- +------------+-------+--------------+
| blog_id | sub_cat_id | title | created_date |
+-------- +------------+-------+--------------+
| 1 | 1 | ABC | 2018-05-25 |
| 2 | 1 | ABC | 2018-05-22 |
| 3 | 2 | ABC | 2018-05-23 |
| 4 | 2 | ABC | 2018-05-21 |
| 5 | 2 | ABC | 2018-05-20 |
| 6 | 8 | ABC | 2018-05-15 |
+-------- +------------+-------+--------------+
Your approach is fine, but your query is not. In particular, MySQL does not guarantee the order of evaluation of expressions in a
SELECT
, so you should not assign a variable in one expression and use it in another.Fortunately, you can combine the assignments into a single expression:
For this query, you want indexes. I think this will work:
type, sub_cat_id, created_date)
. Unfortunately, thegroup by
will still require sorting the data. In more recent versions of MySQL, I think you need to do the sorting in a subquery and then thern
assignment afterwards.I do wonder if this formulation could be made to be more effective:
For this, you want an index on
blog(type, sub_cat_id, created_at)
.