So my problem is the following. Consider this query:
SELECT
P.id,
(SELECT barcode FROM product WHERE publisher_id = P.id LIMIT 1) AS barcode_sample
FROM
publisher P
WHERE
P.name LIKE '%tes%'
This is really about just returning the publisher ids and one barcode (any) as an example from the products. Now this query runs fast and gives what I need but I like to keep things at their place so I tried the following query:
SELECT
P.id,
B.barcode AS barcode_sample
FROM
publisher P
LEFT JOIN
(
SELECT
publisher_id,
MAX(barcode) AS barcode
FROM
product
GROUP BY
publisher_id
) B
ON P.id = B.publisher_id
WHERE
P.name LIKE '%tes%'
Which does almost the same but with a subquery join and group by. Now I'd expect MySQL to first eliminate the rows from the subquery (like a where) to only group by the publisher_id-s I need for the join. But apparently it's not that intelligent and just reads all the rows and does a resource consuming group by.
Here are the explains in order:
+----+--------------------+---------+-------+------------------+------------------+---------+--------------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+-------+------------------+------------------+---------+--------------+-------+--------------------------+
| 1 | PRIMARY | P | index | NULL | name | 452 | NULL | 94004 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | product | ref | idx_publisher_id | idx_publisher_id | 5 | finance.P.id | 210 | Using where |
+----+--------------------+---------+-------+------------------+------------------+---------+--------------+-------+--------------------------+
+----+-------------+------------+-------+---------------+------------------+---------+------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+------------------+---------+------+----------+--------------------------+
| 1 | PRIMARY | P | index | NULL | name | 452 | NULL | 94004 | Using where; Using index |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 64829 | |
| 2 | DERIVED | product | index | NULL | idx_publisher_id | 5 | NULL | 21713216 | |
+----+-------------+------------+-------+---------------+------------------+---------+------+----------+--------------------------+
My question is can I somehow achieve what I want in a semantically better (better looking) way or do I have to learn to live with this ugly but fast query?
Updated queries and examine results with a WHERE clause