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 (
    394479, 394984, 395737, 395770, 396304, 
    396353, 396355, 397091, 397660, 398395, 
    398396, 398401, 398430, 398960, 398964, 
    398997, 399704, 399732, 399740, 399746, 
    399747, 400281, 400282, 400317
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00210

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 (394479,394984,395737,395770,396304,396353,396355,397091,397660,398395,398396,398401,398430,398960,398964,398997,399704,399732,399740,399746,399747,400281,400282,400317))"
          }
        },
        {
          "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
394479 6649,17422,3M
394984 20,17421,3M
395737 20,17421,3M
395770 20,17421,3M
396304 20,17421,3M
396353 20,17421,3M
396355 20,17421,3M
397091 6649,17422,3M
397660 6649,17422,3M
398395 20,17421,3M
398396 20,17421,3M
398401 20,17421,3M
398430 20,17421,3M
398960 20,17421,3M
398964 20,17421,3M
398997 20,17421,3M
399704 20,17421,3M
399732 20,17421,3M
399740 6649,17422,3M
399746 20,17421,3M
399747 20,17421,3M
400281 20,17421,3M
400282 20,17421,3M
400317 20,17421,3M