- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу

VK приобрела 70% в структуре компании-разработчика red_mad_robot
Которая участвовала в создании RuStore
Оксана Мамчуева
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
Как средствами MySQL найти пересечение или разницу двух SELECT?
Таблицы по несколько миллионов записей. Прямо использовать WHERE id NOT IN не выходит.
Пока в голову приходит только array_diff в php использовать.
Есть еще варианты?
попробуйте так, может и прокатит..
индексы по полю id должны быть на обоих таблицах.
если не прокатит, то можно тупо и в лоб за несколько итераций, меняя диапазон отбора
---------- Добавлено 20.03.2016 в 11:22 ----------
Прямо использовать WHERE id NOT IN не выходит.
эээ... пересечение - это WHERE t1.id=t2.id, в Вашем условии - дополнение (кажись так это называется).
Нужно потестить, я так навскидку, но думаю join должен работать
и разница
но я не уверен .что второй запрос будет работать.
и разница
насколько я помню, не равенство медленно работает.
вспомнил еще рабочий финт ушами с левым джойном :)
запрос выдаст id из первой таблицы, которых нет во второй.
переставив таблицы местами можно получить id из второй таблицы, которых нет в первой.
Попробовал с джоинами.
Выборка от 15 до 45 секунд, в зависимости от текушей нагрузки сервака.
Вариант на той же базе с теми же условиями
укладывается в 1-3 секунды.
Есть какие варианты ускорить запрос с джоинами?
sidorka,
Покажите структуру таблиц с ключами.
И уточните задачу, в первом посте у Вас просто найти пересечение, а потом Вы добавляете условие category_id - задачи несколько разные
Ваш вариант в 5 посте - заведомо трэш в меру избыточного вложенности запроса.
В общем случае запрос
select distinct(a.id) from table1 a left join table2 b on a.id=b.id where b.id is not null
должен работать быстро, при условии наличия ключей на id и если поля id полностью одинакового типа.
Если нужно добавить id категории, то правильнее так
select distinct(a.id) from table1 a left join table2 b on a.id=b.id and a.category_id=b.category_id and a.category_id=1 and b.category_id=1 where b.id is not null
Разумеется - ключи на category_id тоже должны быть и должны быть полностью одинаковые по типу тоже.
Частая ошибка с ключами - int(11) и int(10) или int и bigint - разные вещи и скукоживаются сильно хуже.
p.s.: Можно так же попробовать добавить к обоим запросам group by a.id в конце - может сказаться сильно положительно на результате.
Попробовал с джоинами.
Выборка от 15 до 45 секунд, в зависимости от текушей нагрузки сервака.
Есть какие варианты ускорить запрос с джоинами?
Так нафига джойните вложенный селект то?
у вас должно в таблице keywords быть поле равное полю идентификатора секции.
Вы смешали и кашу и мед и еще кое что.
Опишите конкретно что надо и покажите поля связанные с запросом
Требуется из таблицы keywords выбрать записи в нужной категории, которых нет в таблице pages с этой же категорией. Но это просто более частный случай нахождения пересечения - ограничение выборки.
По структуре таблиц
keywords - id - int(11), category_id - int(11) и другие к запросу не относящиеся и в выборку не попадающие. Индексы - первичный id и индекс category_id.
pages - id - int(11), category_id - int(11), keyword_id - int(11) и другие к запросу не относящиеся и в выборку не попадающие. Индексы - первичный id, составной уникальный (category_id,keyword_id)
Проверил вариант такой на основе предложенного - очень долго, не дождался ответа, прибил процесс руками после третьей минуты.
---------- Добавлено 20.03.2016 в 16:59 ----------
Запрос с вложенным селектом показывает стабильно 10-15 секунд.
Попробовал еще один вложить селект - результат тот же. Прироста не дало
---------- Добавлено 20.03.2016 в 17:03 ----------
Если ограничить первый запрос без вложенного подзапроса лимитами, то выборка 10к проходит за 40-50 сек, что не гуд и все равно мало.
---------- Добавлено 20.03.2016 в 17:23 ----------
edogs, второй вариант, предложенный вами, не прошел - 89970 rows in set (6 min 22.64 sec).
а вот такой выдает пустой результат
этот тоже пустой
---------- Добавлено 20.03.2016 в 17:26 ----------
Ваш вариант в 5 посте - заведомо трэш в меру избыточного вложенности запроса.
этот вариант пока единственный условно пригодный
sidorka,
Посмотрите на свои запросы.
Вы пишите is null, а не is not null.
Таким образом ищете не пересечение, а как раз наоборот - записи которые есть в первой таблице и которых нет во второй.
Разница - не только в результате (который в Вашей версии неверен), но и в скорости (найти отсутствующие записи сложнее чем пересекающиеся и там другой способ нужен).
edogs, на данный момент именно это и нужно - найти разницу между выборкой 1 и выборкой 2.
Требуется из таблицы keywords выбрать записи в нужной категории, которых нет в таблице pages с этой же категорией.
С совпадением двух выборок проще выходит, это я уже осилил.
edogs, на данный момент именно это и нужно - найти разницу между выборкой 1 и выборкой 2.
Ок, но все же не надо использовать запрос который мы писали для для пересечения напрямую для поиска разницы. Это разные вещи в принципе.
Требуется из таблицы keywords выбрать записи в нужной категории, которых нет в таблице pages с этой же категорией.
Попробуйте примерно так
select a.id from keywords as a where a.cat=1 and a.id not in ( select distinct(b.keyid) from pages as b where b.cat=1 )