Альтернатива «где col в (список)» для MySQL - PullRequest
5 голосов
/ 19 марта 2010

Привет, у меня есть следующая таблица T:

id    1   2    3    4
col   a   b    a    c

Я хочу сделать выборку, которая возвращает id, col, когда группа по (col), имеющая count (col)> 1

Один из способов сделать это -

SELECT id,col FROM T 
   WHERE col IN (SELECT col FROM T GROUP BY(col) HAVING COUNT(col)>1);

Интерн select (справа) возвращает 'a', а основной (слева) вернет 1, a и 3, a

Проблема в том, что оператор where находится на очень медленном уровне. В моем реальном случае результаты внутреннего выбора имеют много значений, около 70000, и это занимает несколько часов.

Сейчас гораздо быстрее сделать внутренний выбор и главный выбор, получив все идентификаторы и upcs, и выполнить пересечение локально. MySQL должен уметь эффективно обрабатывать такие запросы.

Могу ли я заменить место для соединения или что-то более быстрое?

Спасибо

Ответы [ 2 ]

5 голосов
/ 19 марта 2010

Вы можете попробовать, если использование INNER JOIN ускоряет процесс

  • Убедитесь, что у вас есть индекс col
  • Индекс покрытия на col, id может повысить вашу производительность

Оператор SQL

SELECT  T.id, T.col
FROM    T
        INNER JOIN (
          SELECT   col
          FROM     T
          GROUP BY col
          HAVING COUNT(*) > 1
        ) tcol ON tcol.col = T.col
2 голосов
/ 19 марта 2010
SELECT  id, col
FROM    t t1
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    t t2
        WHERE   t2.col = t1.col
                AND t2.id <> t1.id
        )

Убедитесь, что у вас есть индекс для (col)InnoDB) или (col, id)MyISAM)

Внутренний запрос прекратит оценку, как только найдет первое совпадающее значение. С индексом это произойдет после одного поиска по индексу с максимум двумя просмотрами индекса.

...