Primero, puede intentar agregar índices a los campos ProgramName y CustID si aún no los tiene.
Eliminación de duplicados
Puede agrupar sus registros para identificar duplicados y, mientras lo hace, obtenga el valor de ID mínimo para cada grupo. Luego, simplemente elimine todos los registros cuya ID no sea una de las MinID.
Método dentro de la cláusula
delete from
ProgramsList
where
id not in
(select min(id) as MinID
from ProgramsList
group by ProgramName, CustID)
Método de unión
Es posible que deba ejecutar esto más de una vez, si hay muchos miembros por grupo.
DELETE P
FROM ProgramsList as P
INNER JOIN
(select count(*) as Count, max(id) as MaxID
from ProgramsList
group by ProgramName, CustID) as A on A.MaxID = P.id
WHERE A.Count >= 2
Algunas personas tienen problemas de rendimiento con In-Clause, otras no. Depende mucho de tus índices y demás. Si uno es demasiado lento, pruebe con el otro.
Relacionado:https://stackoverflow.com/a/4192849/127880