SQL : élimination des doublons d’une table

SQL : élimination des doublons d'une tableEn 2020, je vous avais écrit cette requête pourrie dont l’objet était l’élimination des doublons constatés dans le champ content_hash de la table ttrss_entries, en privilégiant la conservation des premières lignes ajoutées.

Ici, le moteur de base de données utilisé est MariaDB. Il dispose depuis la version 10.3 de l’opérateur EXCEPT, comme dans SQL Server et PostgreSQL. Pour Oracle, il s’agit de MINUS.

Une requête bien pourrie

Le temps d’exécution de cette requête et la consommation CPU induite sont incompatibles avec de fortes volumétries.

1er jet : une requête peu optimisée
DELETE FROM ttrss_entries
WHERE id IN
(
	-- Sélection de tous les id des enregistrements en double sur le champ content_hash
	SELECT id FROM ttrss_entries
	WHERE content_hash IN
	(
		SELECT content_hash FROM ttrss_entries
		GROUP BY content_hash
		HAVING COUNT(content_hash)>1
	)
	-- Sélection de laquelle on retire les lignes étant ajoutées en 1er
	EXCEPT
	SELECT MIN(id) FROM ttrss_entries
	GROUP BY content_hash
	HAVING COUNT(content_hash)>1
);
2e jet : une requête optimisée, mais pourrie quand même !
START TRANSACTION;
DELETE FROM ttrss_entries
WHERE id IN
(
	WITH 
		req_titles AS
		(
			SELECT
				id,
				MD5(title) md5title
			FROM
				ttrss_entries
		),
		req_doublons AS
		(
			SELECT md5title,MIN(ID) minid FROM req_titles
			GROUP BY md5title
			HAVING COUNT(md5title)>1	
		)
	SELECT id FROM req_titles
	WHERE md5title IN
	(
		SELECT md5title FROM req_doublons
	)
	EXCEPT
	SELECT minid FROM req_doublons
);
COMMIT;

Une requête simple et rapide à exécuter !

Je ai testé cette requête sur FreshRSS. son objet est d’éliminer les doublons sur le titre et sur le contenu.

	DELETE t1 
	FROM freshrss.test_entry AS t1, freshrss.test_entry AS t2
	WHERE 
		t1.id > t2.id
	AND
	( 
		t1.title = t2.title
		OR
		t1.content_bin = t2.content_bin
	)
	;

SQL /