SELECT 
  products_categories.product_id, 
  GROUP_CONCAT(
    IF(
      products_categories.link_type = "M", 
      CONCAT(
        products_categories.category_id, 
        "M"
      ), 
      products_categories.category_id
    )
  ) AS category_ids 
FROM 
  products_categories 
  INNER JOIN categories ON categories.category_id = products_categories.category_id 
  AND categories.storefront_id IN (0, 1) 
  AND (
    categories.usergroup_ids = '' 
    OR FIND_IN_SET(0, categories.usergroup_ids) 
    OR FIND_IN_SET(1, categories.usergroup_ids)
  ) 
  AND categories.status IN ('A', 'H') 
WHERE 
  products_categories.product_id IN (
    322386, 322409, 323703, 323719, 323720, 
    323729, 323737, 323745, 324479, 324482, 
    324483, 324505, 324516, 325794, 325832, 
    326336, 326343, 326355, 326361, 327103, 
    327115, 327664, 327681, 327714
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00131

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "39.92"
    },
    "grouping_operation": {
      "using_filesort": false,
      "nested_loop": [
        {
          "table": {
            "table_name": "products_categories",
            "access_type": "range",
            "possible_keys": [
              "PRIMARY",
              "link_type",
              "pt"
            ],
            "key": "pt",
            "used_key_parts": [
              "product_id"
            ],
            "key_length": "3",
            "rows_examined_per_scan": 72,
            "rows_produced_per_join": 72,
            "filtered": "100.00",
            "using_index": true,
            "cost_info": {
              "read_cost": "7.52",
              "eval_cost": "7.20",
              "prefix_cost": "14.72",
              "data_read_per_join": "1K"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ],
            "attached_condition": "(`goimagine`.`products_categories`.`product_id` in (322386,322409,323703,323719,323720,323729,323737,323745,324479,324482,324483,324505,324516,325794,325832,326336,326343,326355,326361,327103,327115,327664,327681,327714))"
          }
        },
        {
          "table": {
            "table_name": "categories",
            "access_type": "eq_ref",
            "possible_keys": [
              "PRIMARY",
              "c_status",
              "p_category_id"
            ],
            "key": "PRIMARY",
            "used_key_parts": [
              "category_id"
            ],
            "key_length": "3",
            "ref": [
              "goimagine.products_categories.category_id"
            ],
            "rows_examined_per_scan": 1,
            "rows_produced_per_join": 3,
            "filtered": "5.00",
            "cost_info": {
              "read_cost": "18.00",
              "eval_cost": "0.36",
              "prefix_cost": "39.92",
              "data_read_per_join": "9K"
            },
            "used_columns": [
              "category_id",
              "usergroup_ids",
              "status",
              "storefront_id"
            ],
            "attached_condition": "((`goimagine`.`categories`.`storefront_id` in (0,1)) and ((`goimagine`.`categories`.`usergroup_ids` = '') or (0 <> find_in_set(0,`goimagine`.`categories`.`usergroup_ids`)) or (0 <> find_in_set(1,`goimagine`.`categories`.`usergroup_ids`))) and (`goimagine`.`categories`.`status` in ('A','H')))"
          }
        }
      ]
    }
  }
}

Result

product_id category_ids
322386 20,17421,3M
322409 20,17421,3M
323703 20,17421,3M
323719 20,17421,3M
323720 20,17421,3M
323729 20,17421,3M
323737 20,17421,3M
323745 20,17421,3M
324479 20,17421,3M
324482 20,17421,3M
324483 20,17421,3M
324505 20,17421,3M
324516 20,17421,3M
325794 20,17421,3M
325832 20,17421,3M
326336 20,17421,3M
326343 20,17421,3M
326355 20,17421,3M
326361 20,17421,3M
327103 20,17421,3M
327115 20,17421,3M
327664 20,17421,3M
327681 20,17421,3M
327714 20,17421,3M