Forum Webscript.Ru

Общие => Базы данных => Тема начата: Altaxar от 06 Января 2007, 15:38:38

Название: Помагите с запросом
Отправлено: Altaxar от 06 Января 2007, 15:38:38
Есть таблица "ааа" и есть колонка "bbb", мне нужно удалить все повторяющиеся(дублирующиеся) записи по колонке "bbb".
Дело в том что записей очень много, если самым тупым запросом задать то длительность будет большая N*N, подскажите более быстрый запрос.
Название: Помагите с запросом
Отправлено: andymc от 12 Января 2007, 00:54:19
Простой вариант...

DELETE *
FROM aaa
WHERE bbb NOT IN
     (SELECT DISTINCT bbb
      FROM aaa);


Если надо быстрее, то можно гипотетически предположить
1. SELECT DISTINCT bbb FROM aaa
2. Заменить таблицу aaa на таблицу созданную по запросу 1)


Думаем дальше. Наверняка есть поле id (первичный ключ)
1. SELECT DISTINCT bbb, id FROM aaa
2. SELECT * id FROM aaa
3. array_diff(1,2)
4. Удалить все строки с id из массива 3)


Ни один из вариантов конечно не оптимален. I tried :(
Название: Помагите с запросом
Отправлено: Altaxar от 12 Января 2007, 18:01:55
Цитировать
andymc

Спасибо.
Думаю ускорит если столбец bbb в MySQL сделать также ключевым. тогда он столбец сделает не как список, а более удобный для поиска и DISTINCT заработает быстрее.
2 вариант неудобен, у меня очень маленький процент повторение(0.1 - 1 %). И поток меж PHP и MySQL немалый будет.
3 вариант сейчас и использую.

Так как у меня малый процент совпадения такой вариант возник:
DELETE *
FROM aaa
WHERE bbb IN
     (SELECT bbb FROM aaa WHERE COUNT(bbb)>1 GROUP BY bbb);
Таким образом скорость SELECT GROUP ровна N*N а у меня N*N/1000 до N*N/100 из-за процента и DELETE также ровна N, связ меж ними от 1 до N в сумме N/2 это максемальный и зависит от количества совпадений так что у меня N/2000 до N/200 в итоге получаем f1(N*N/1000 до N*N/100)+f2(N)+f3(N/2000 до N/200). Думаю это оптемально.
Название: Помагите с запросом
Отправлено: andymc от 13 Января 2007, 10:23:31
Цитировать
SELECT bbb FROM aaa WHERE COUNT(bbb)>1 GROUP BY bbb
Меня терзают смутные сомнения, работает ли это ...
будет время проверю...
Впрочем сама идея заменить DISTINCT на COUNT интересна
Название: Помагите с запросом
Отправлено: Akvar от 20 Августа 2007, 12:35:06
Цитировать
SELECT bbb FROM aaa WHERE COUNT(bbb)>1 GROUP BY bbb

такое конечно не работает... так как при большой базе - сжирает память...

/ данная тема старая...  но хочется поднять...  так как в нете тяжело найти ответ - все неработающие идеи...
но необходимо расширить задачу:
1) при малом количестве совпадений скрипт выполнялся очень быстро...
2) при большом количестве совподений ( более 50% - не загибался сервер при количестве записий около 1-го милиона )

Делал кто-то такое ?
Название: Помагите с запросом
Отправлено: Akvar от 20 Августа 2007, 14:27:25
Вобщем посидел, подумал - поэксперементировал...
и старался избавится от парсинга и повторяющихся записей..
вот что получилось : ( помоемому самый быстрый вариант :)

CREATE TEMPORARY TABLE stack_1 SELECT t1.id, t1.b_email from baza AS t1 where EXISTS ( SELECT * FROM baza AS t2 WHERE t2.b_email=t1.b_email AND t2.id!=t1.id );
CREATE TEMPORARY TABLE stack_2 SELECT MIN(id) as id FROM stack_1 GROUP BY b_email;
DELETE stack_1 FROM stack_2, stack_1 WHERE stack_2.id=stack_1.id;
DELETE baza FROM stack_1, baza WHERE stack_1.id=baza.id;
Название: Помагите с запросом
Отправлено: Altaxar от 20 Августа 2007, 15:33:21
DROP TABLE IF EXISTS stack;
CREATE TABLE stack SELECT id, b_email FROM aaa group by b_email;
DROP TABLE IF EXISTS aaa;
RENAME TABLE stack TO aaa;

Я еще такое попробывал на большое количество, у меня работает
Название: Помагите с запросом
Отправлено: sanika от 07 Сентября 2007, 11:17:43
Не хочу создавать новую тему, может тут отпишусь. Есть запрос

select DISTINCT nazv, vznos, id_sozd, reiting, pict from company order by \'vznos\'

типа выбирает уникальные записи, при этом сортирует по значению поля "взнос".
а как сделать сортировку не по значению поля, а по количеству повторяющихся записей?
Название: Помагите с запросом
Отправлено: andymc от 07 Сентября 2007, 14:56:57
ORDER BY COUNT(1) ?
Название: Помагите с запросом
Отправлено: sanika от 07 Сентября 2007, 15:29:13
а что такое (1)?
Название: Помагите с запросом
Отправлено: sanika от 07 Сентября 2007, 15:32:05
не работает((
Название: Помагите с запросом
Отправлено: Altaxar от 08 Сентября 2007, 03:07:50
select nazv, vznos, id_sozd, reiting, pict, count(vznos) as con from company group by vznos order by con
Название: Помагите с запросом
Отправлено: sanika от 10 Сентября 2007, 12:52:08
Altaxar Огромное спасибо - работает. А что такое con?
Название: Помагите с запросом
Отправлено: andymc от 10 Сентября 2007, 12:59:42
sanika
Ты удивишься, но в SQL запросах возможно и такое: SELECT col FROM yourTable WHERE 1 < 0 Где 1 - номер поля
А con - это отсюда count(vznos) as con
Название: Помагите с запросом
Отправлено: Altaxar от 11 Сентября 2007, 11:42:28
group by vznos - груперует по столбцу vznos
count(vznos) as con - определяет количество совпадений и передает это в имя con, написать можеш, что хочеш(естествено в рамках допустимого).
order by con - сортирует по полученному столбцу.
естественно на выходе у тебя будет столбец con
Название: Помагите с запросом
Отправлено: sanika от 11 Сентября 2007, 11:57:11
Altaxar
спасибо большое