Я использовал WAMP некоторое время теперь, и от того, что я собрал его довольно надежное. Установка является бризом, и пользовательский интерфейс является довольно дружественным.
Например, вы можете:
CREATE TABLE tmp ...
INSERT INTO tmp SELECT DISTINCT * FROM t;
DROP TABLE t;
ALTER TABLE tmp RENAME TO t;
DELETE FROM table
WHERE something NOT IN
(SELECT MAX(s.something)
FROM table As s
GROUP BY s.this_thing, s.that_thing);
Сначала вам нужно решить, какой ваших «дубликатов» вы сохраните. Если все столбцы равны, хорошо, вы можете удалить любой из них ... Но, может быть, вы хотите оставить только самые последние или какой-то другой критерий?
Самый быстрый способ зависит от вашего ответа на вопрос выше, а также по проценту дубликатов в таблице. Если вы выбросите 50% строк, лучше выполнить CREATE TABLE ... AS SELECT DISTINCT ... FROM ...;
, а если вы удалите 1% строк, используя УДАЛЕНИЕ лучше.
Также для таких операций обслуживания, как правило, хорошо установить work_mem
на хороший кусок вашей оперативной памяти: запустите EXPLAIN, проверьте количество N сортов / хэшей, и установите work_mem в RAM / 2 / N. Используйте много RAM; это хорошо для скорости. Пока у вас есть только одно одновременное соединение ...
Эта функция удаляет дубликаты без удаления индексов и делает это с любой таблицей.
Использование: select remove_duplicates ('mytable');
--- --- remove_duplicates(tablename) removes duplicate records from a table (convert from set to unique set) --- CREATE OR REPLACE FUNCTION remove_duplicates(text) RETURNS void AS $$ DECLARE tablename ALIAS FOR $1; BEGIN EXECUTE 'CREATE TEMPORARY TABLE _DISTINCT_' || tablename || ' AS (SELECT DISTINCT * FROM ' || tablename || ');'; EXECUTE 'DELETE FROM ' || tablename || ';'; EXECUTE 'INSERT INTO ' || tablename || ' (SELECT * FROM _DISTINCT_' || tablename || ');'; EXECUTE 'DROP TABLE _DISTINCT_' || tablename || ';'; RETURN; END; $$ LANGUAGE plpgsql;
Я работаю с PostgreSQL 8.4. Когда я запустил предложенный код, я обнаружил, что на самом деле он не удаляет дубликаты. При выполнении некоторых тестов я обнаружил, что добавление «DISTINCT ON (duplicate_column_name)» и «ORDER BY duplicate_column_name» помогло. Я не гуру SQL, я нашел это в документе PostgreSQL 8.4 SELECT ... DISTINCT.
CREATE OR REPLACE FUNCTION remove_duplicates(text, text) RETURNS void AS $$
DECLARE
tablename ALIAS FOR $1;
duplicate_column ALIAS FOR $2;
BEGIN
EXECUTE 'CREATE TEMPORARY TABLE _DISTINCT_' || tablename || ' AS (SELECT DISTINCT ON (' || duplicate_column || ') * FROM ' || tablename || ' ORDER BY ' || duplicate_column || ' ASC);';
EXECUTE 'DELETE FROM ' || tablename || ';';
EXECUTE 'INSERT INTO ' || tablename || ' (SELECT * FROM _DISTINCT_' || tablename || ');';
EXECUTE 'DROP TABLE _DISTINCT_' || tablename || ';';
RETURN;
END;
$$ LANGUAGE plpgsql;