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 (
    276551, 276583, 279115, 279095, 276805, 
    276567, 276811, 276584, 276574, 276560, 
    276580, 276566, 279097, 276812, 276815, 
    276803, 276804, 279104, 279255, 276577, 
    279262, 279250, 283189, 287048
  ) 
GROUP BY 
  products_categories.product_id

Query time 0.00181

JSON explain

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "40.48"
    },
    "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": 73,
            "rows_produced_per_join": 73,
            "filtered": "100.00",
            "using_index": true,
            "cost_info": {
              "read_cost": "7.63",
              "eval_cost": "7.30",
              "prefix_cost": "14.93",
              "data_read_per_join": "1K"
            },
            "used_columns": [
              "product_id",
              "category_id",
              "link_type"
            ],
            "attached_condition": "(`goimagine`.`products_categories`.`product_id` in (276551,276583,279115,279095,276805,276567,276811,276584,276574,276560,276580,276566,279097,276812,276815,276803,276804,279104,279255,276577,279262,279250,283189,287048))"
          }
        },
        {
          "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.25",
              "eval_cost": "0.37",
              "prefix_cost": "40.48",
              "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
276551 40,20331,8M
276560 40,20331,8M
276566 40,20331,8M
276567 40,20331,8M
276574 40,20331,8M
276577 40,20331,8M
276580 40,20331,8M
276583 20327,20329,132M
276584 20329,132M
276803 40,20331,8M
276804 40,20331,8M
276805 40,20331,8M
276811 40,20331,8M
276812 40,20331,8M
276815 40,20331,8M
279095 40,20331,8M
279097 40,20331,8M
279104 40,20331,8M
279115 17,2M
279250 147,20327,20328,17M
279255 149,20327,20328,17M
279262 147,20327,20328,17M
283189 147,20327,20328,17M
287048 20329,132M