Query closest matching products I have my products that are classified into topics and their appropriate weight as shown in the example data below.

How do I select the closest matching product for a given id (ASIN)?

For example given ASIN = B01LYQ7HHQ, I can find out the weight in topic 1 is 63% and in topic 2 is 36%. I want to find all products with close weights in topic 1 and 2.

Is there any pre-processing I can do to make this faster?

mysql&gt; select * from productClassification;
+------------+------------+--------------------+
| asin       | topic      | weight             |
+------------+------------+--------------------+
| B01LYQ7HHQ |          1 |  63.44902130267551 |
| B01LYQ7HHQ |          9 |  36.26560242715266 |
| B01LXSHRCW |          1 |  99.66814132315916 |
| B01M11HUG0 |          1 |  99.66947475251457 |
| B01LZF3T03 |          1 |   99.6694739441313 |
| B01M11J5C5 |          1 |  99.66947416301599 |
| B01M1DBCJR |          1 |  99.67470180477409 |
| B01M1DCIFY |          1 |   99.6759830134407 |
| B01M1DAN1S |          1 |  99.67598294206206 |
| B01M1DAC7T |          1 |  99.67598190382282 |
| B01MDU1ORW |          5 |  99.41468709779492 |
| B01MATR1ZN |          1 |  99.10495867903543 |
| B01KWK92UQ |          1 |  99.58003188092593 |
| B01JNZPJ58 |          3 |  21.11376404497454 |
| B01JNZPJ58 |          4 |  78.59396409296829 |
| B01M7MPM53 |          1 |   99.1240145475186 |
| B01KRISTN4 |          5 |   82.6304883031779 |
| B01KRISTN4 |          6 | 17.126526467560705 |
| B01M7XB92L |          8 |  99.60033299266769 |
| B01N0YWECZ |          3 | 21.322298137603465 |
| B01N0YWECZ |          4 |    78.384269855458 |
| B01LS3K2N2 |          6 |  99.08374425882562 |
| B01LPX5H30 |          3 |  99.67616266864002 |
| B01LPX5JCO |          3 |  99.70912736486947 |
| B01LPX5LBI |          3 |  99.72088151396052 |
| B01LPX5NL6 |          3 |  99.71512561650343 |
| B01LPX5PKK |          3 |  99.69963831148516 |
| B01LPX5HA8 |          3 |  99.67616790525699 |
| B01LPX5J7Y |          3 |  99.70072257059286 |
| B01LPX5LNQ |          3 |  99.70179821823663 |
| B01LPX5NVQ |          3 |  99.71315325446342 |
| B01JOCWE0I |          3 |  98.54399854068194 |


Thanks in advance for the help!
I think you are looking something like this.
This will list all products in the same topic id..

SELECT 
   productClassification.asin
 , productClassification.topic
 , productClassification.weight
FROM (
 SELECT 
   productClassification.topic
 FROM
   productClassification
 WHERE
   productClassification.asin = 'B01LYQ7HHQ'
)
 AS
 productClassification_filter
INNER JOIN 
 productClassification
ON
 productClassification.topic = productClassification_filter.topic
AND
  productClassification.asin != 'B01LYQ7HHQ'
ORDER BY 
   productClassification.topic ASC
 , productClassification.weight ASC


Result

asin         topic         weight  
----------  ------  ---------------
B01MATR1ZN       1    99.1049586790
B01M7MPM53       1    99.1240145475
B01KWK92UQ       1    99.5800318809
B01LXSHRCW       1    99.6681413232
B01LZF3T03       1    99.6694739441
B01M11J5C5       1    99.6694741630
B01M11HUG0       1    99.6694747525
B01M1DBCJR       1    99.6747018048
B01M1DAC7T       1    99.6759819038
B01M1DAN1S       1    99.6759829421
B01M1DCIFY       1    99.6759830134


But if you want to limit per topic id you need to use user variables. 
This query will show the 3 best matching products per topic id

SELECT 
   productClassification_ordered_ranked_limited.ASIN
 , productClassification_ordered_ranked_limited.topic
 , productClassification_ordered_ranked_limited.weight
FROM (
  SELECT
    @topic := NULL
  , @rank := 0
)
 AS
  init_user_vars
CROSS JOIN (

SELECT 
   productClassification_ordered_ranked.asin
 , productClassification_ordered_ranked.topic
 , productClassification_ordered_ranked.weight
 , productClassification_ordered_ranked.rank
FROM ( 
  SELECT 
     productClassification_ordered.asin
   , productClassification_ordered.topic
   , productClassification_ordered.weight
   , @rank := (
    CASE
     WHEN @topic := productClassification_ordered.topic
     THEN @rank + 1
     ELSE @rank := 0
    END
     ) AS rank
   , (@topic := productClassification_ordered.topic)
  FROM ( 
    SELECT 
      productClassification.asin
    , productClassification.topic
    , productClassification.weight
    FROM (
      SELECT 
        productClassification.topic
      FROM
        productClassification
      WHERE
        productClassification.asin = 'B01LYQ7HHQ'
      )
      AS
        productClassification_filter
      INNER JOIN 
        productClassification
      ON
        productClassification.topic = productClassification_filter.topic
      AND
        productClassification.asin != 'B01LYQ7HHQ'
      ORDER BY 
        productClassification.topic ASC
      , productClassification.weight ASC

    )
    AS
      productClassification_ordered
  )
   AS
     productClassification_ordered_ranked
  )
   AS 
     productClassification_ordered_ranked_limited
 WHERE
   productClassification_ordered_ranked_limited.rank &lt;= 3 -- limit 3 per topic id


Result

ASIN         topic         weight  
----------  ------  ---------------
B01MATR1ZN       1    99.1049586790
B01M7MPM53       1    99.1240145475
B01KWK92UQ       1    99.5800318809