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 (
    380465, 380470, 380472, 380473, 380476, 
    380508, 381231, 381232, 381248, 381259, 
    381262, 381790, 381809, 381825, 381827, 
    381832, 381834, 382560, 382585, 383096, 
    383141, 383151, 383154, 383157
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00280

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "39.91"
    },
    "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.51",
              "eval_cost": "7.20",
              "prefix_cost": "14.71",
              "data_read_per_join": "1K"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ],
            "attached_condition": "(`goimagine`.`products_categories`.`product_id` in (380465,380470,380472,380473,380476,380508,381231,381232,381248,381259,381262,381790,381809,381825,381827,381832,381834,382560,382585,383096,383141,383151,383154,383157))"
          }
        },
        {
          "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.91",
              "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
380465 6649,17422,3M
380470 6649,17422,3M
380472 6649,17422,3M
380473 6649,17422,3M
380476 6649,17422,3M
380508 20,17421,3M
381231 6649,17422,3M
381232 6649,17422,3M
381248 6649,17422,3M
381259 6649,17422,3M
381262 6649,17422,3M
381790 6649,17422,3M
381809 20,17421,3M
381825 20,17421,3M
381827 20,17421,3M
381832 20,17421,3M
381834 20,17421,3M
382560 20,17421,3M
382585 20,17421,3M
383096 20,17421,3M
383141 6649,17422,3M
383151 6649,17422,3M
383154 20,17421,3M
383157 6649,17422,3M