sv2109 Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Столкнулся с интересной задачей в одном проекте над которым сейчас работаю. Есть таблица (упрощенный ее вариант): CREATE TABLE `test` ( `id` int(11) NOT NULL, `word` varchar(64) CHARACTER SET utf8 NOT NULL, UNIQUE KEY `index` (`id`,`word`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8_general_ci; INSERT INTO `test` (`id`, `word`) VALUES (1, 'baz'), (1, 'foo'), (2, 'bar'), (2, 'foo'), (3, 'bar'), (3, 'baz'), (3, 'foo'); Задача: 1. найти все 'id', у которых 'word' равно 'bar' И 'foo' (должно найти 2 и 3) 2. очень важно, чтобы запрос работал максимально быстро, так как в реальной таблице сотни тысяч записей Казалось бы что может быть проще? Если нужна логика "или" то все действительно очень просто: SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` Если же логика "и" то сразу хочется написать: SELECT `id` FROM `test` WHERE `word` = 'bar' AND `word` = 'foo' GROUP BY `id` но, такой запрос ничего не найдет, так как 'word' не может одновременно быть и 'bar' и 'foo' И вот сижу и думаю. Решения я нашел, но оно мне не нравится, так как оно сложное и работает раза в 3 медленнее, чем запрос с "OR" Может есть какое-то простое и быстрое решение которого я в час ночи в упор не вижу? Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Столкнулся с интересной задачей в одном проекте над которым сейчас работаю. Есть таблица (упрощенный ее вариант): CREATE TABLE `test` ( `id` int(11) NOT NULL, `word` varchar(64) CHARACTER SET utf8 NOT NULL, UNIQUE KEY `index` (`id`,`word`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8_general_ci; INSERT INTO `test` (`id`, `word`) VALUES (1, 'baz'), (1, 'foo'), (2, 'bar'), (2, 'foo'), (3, 'bar'), (3, 'baz'), (3, 'foo'); Задача: 1. найти все 'id', у которых 'word' равно 'bar' И 'foo' (должно найти 2 и 3) 2. очень важно, чтобы запрос работал максимально быстро, так как в реальной таблице сотни тысяч записей Казалось бы что может быть проще? Если нужна логика "или" то все действительно очень просто: SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` Если же логика "и" то сразу хочется написать: SELECT `id` FROM `test` WHERE `word` = 'bar' AND `word` = 'foo' GROUP BY `id` но, такой запрос ничего не найдет, так как 'word' не может одновременно быть и 'bar' и 'foo' И вот сижу и думаю. Решения я нашел, но оно мне не нравится, так как оно сложное и работает раза в 3 медленнее, чем запрос с "OR" Может есть какое-то простое и быстрое решение которого я в час ночи в упор не вижу? http://www.dofactory.com/sql/where-in SELECT Id, CompanyName, City, Country FROM Supplier WHERE Country IN ('USA', 'UK', 'Japan') Ну и если что, могу напомнить как поменять цвет кнопочки .button( backround: red; ) 1 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Еще так можно SELECT `id` FROM `test` WHERE `word` in ('bar', 'foo') GROUP BY `id` Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 мимо :)это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 мимо :) это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Столкнулся с интересной задачей в одном проекте над которым сейчас работаю. Есть таблица (упрощенный ее вариант): CREATE TABLE `test` ( `id` int(11) NOT NULL, `word` varchar(64) CHARACTER SET utf8 NOT NULL, UNIQUE KEY `index` (`id`,`word`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8_general_ci; INSERT INTO `test` (`id`, `word`) VALUES (1, 'baz'), (1, 'foo'), (2, 'bar'), (2, 'foo'), (3, 'bar'), (3, 'baz'), (3, 'foo'); Задача: 1. найти все 'id', у которых 'word' равно 'bar' И 'foo' (должно найти 2 и 3) 2. очень важно, чтобы запрос работал максимально быстро, так как в реальной таблице сотни тысяч записей Казалось бы что может быть проще? Если нужна логика "или" то все действительно очень просто: SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` Если же логика "и" то сразу хочется написать: SELECT `id` FROM `test` WHERE `word` = 'bar' AND `word` = 'foo' GROUP BY `id` но, такой запрос ничего не найдет, так как 'word' не может одновременно быть и 'bar' и 'foo' И вот сижу и думаю. Решения я нашел, но оно мне не нравится, так как оно сложное и работает раза в 3 медленнее, чем запрос с "OR" Может есть какое-то простое и быстрое решение которого я в час ночи в упор не вижу? http://www.dofactory.com/sql/where-in SELECT Id, CompanyName, City, Country FROM Supplier WHERE Country IN ('USA', 'UK', 'Japan') Ну и если что, могу напомнить как поменять цвет кнопочки .button( backround: red; ) 1 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Еще так можно SELECT `id` FROM `test` WHERE `word` in ('bar', 'foo') GROUP BY `id` Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 мимо :)это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 мимо :) это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Еще так можно SELECT `id` FROM `test` WHERE `word` in ('bar', 'foo') GROUP BY `id` Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 мимо :)это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 мимо :) это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 мимо :)это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 мимо :) это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 мимо :) это я с самого начала попробовал `word` IN ('bar', 'foo') это аналог `word` = 'bar' OR `word` = 'foo' А логика нужна "AND" запрос SELECT `id` FROM `test` WHERE `word` IN ('bar', 'foo') GROUP BY `id` возвращает 1,2,3 а нужно 2,3 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
snastik Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий И не сбивайте нас с толку, ID считается уникальным (я кстати сразу и не заметил "дубли" ID) Переобзовите вот Марк с языка снял! Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 вот Марк с языка снял! А ты предыдущий снял пока я его набирал :ugeek: Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
sv2109 Опубліковано: 20 липня 2016 Автор Share Опубліковано: 20 липня 2016 Тогда надо Лефт Джойнить - а это будет медленнее и запрос громоздкий это я и сделал, но подумал, что может быть есть более красивое решение, которого я не вижу, поэтому и создал эту тему. И не сбивайте нас с толку ID считается уникальным (я кстати сразу и не заметил "дубли" ID)уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 20 липня 2016 Share Опубліковано: 20 липня 2016 ... уникальный ключ может быть по нескольким полям, в данном случае это вообще не существенно и ничего не меняет, я добавил ключ, чтобы в phpmyadmin можно было записи редактировать, можно было и вообще ее не добавлять. Да просто мы привыкли что ID уникальный всегда. Я даже не посмотрел что ID одинаковый у некоторых элементов и выдал код. А так бы сразу выдал LJ Надіслати Поділитися на інших сайтах More sharing options... n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options... snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
n3bo Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Надіслати Поділитися на інших сайтах More sharing options...
ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' Надіслати Поділитися на інших сайтах More sharing options...
snastik Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Не знаю насколько оптимизированный, но как вариант: SELECT `id` FROM test t WHERE (select count(*) from test t2 WHERE t2.word IN ('bar', 'foo') AND t2.id=t.id) >=2 GROUP BY t.test Это уложит на 100 000 записей сервер на полдня, так как для каждой записи вы создаете итерацию подзапроса с выборкой из всей таблицы. SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(*)=2 или вот так если у mysql ума хватит SELECT `id` FROM `test` WHERE `word` = 'bar' OR `word` = 'foo' GROUP BY `id` having count(distinct `word`)=2 having - не самый быстрый метод, а тем более по неиндексированной сущности. Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' В данном контексте - это идеальный вариант. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Как-то так. SELECT t1.id FROM test AS t1 INNER JOIN test AS t2 ON t1.id = t2.id AND t2.word = 'bar' WHERE t1.word = 'foo' У меня с самого начала был почти такой же вариант: SELECT t.id FROM `test` t LEFT JOIN `test` t2 ON (t.id = t2.id) WHERE t.word = 'bar' AND t2.word = 'foo' GROUP BY t.id Но он мне не нравится, потому что: 1. Я этого не указал в задании, думал и так понятно, но в реальном запросе не обязательно будет 2 слова, там может быть и 3 и 5 и 10, а иногда возможно даже и больше. 2. В реальной базе не одна, а 2 таблицы и для каждого нового слова нужно подключать не одну, а 2 новых таблицы 3. В реальной таблице могут быть десятки и даже сотни тысяч записей. И если взять например таблицу с 100 тыс. записей, осуществить выборку по 10 словам (подключив по 2 доп. таблицы для каждого слова) то это очень сильно скажется на скорости запроса, запрос будет выполняться больше 10 раз медленнее, чем аналогичный с логикой "OR", так как в данном случае MySQL будет искать по каждой подключенной таблице отдельно. Поэтому я и создал эту тему в надежде что может есть красивое решение, которого я не вижу. Как-то сразу не поверил, что для такой, казалось бы простой задачи, нету простого и быстрого решения. Но, увы :( В любом случае, всем спасибо за потраченное время, оно не потрачено напрасно, мы все узнали что-то новое, получили новые знания, которые нам пригодятся в будущем. Тема открыта - если у кого-то будут новые идеи - пишите. Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. 1 Надіслати Поділитися на інших сайтах More sharing options...
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов. во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 во! а вот это уже круто :) Это то, что мне нужно было - взгляд на проблему под другим углом, так как я зациклился на варианте с джойнами и ничего другого уже просто не мог увидеть, хотя подсознательно понимал что должно быть более красивое решение. Нужно будет проверить скорость на реальной базе, но думают со скоростью все должно быть нормально, во всяком случае она должна быть намного больше чем вариант с джойнами. На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 UNION еще с простыми запросами проверьте на большой базе Тоже вариант Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 На большой базе COUNT тоже мега тормоз и плюс временные таблицы... (про подсчет количества товаров в категориях напомнить ;) ) Иногда будет быстрее быстрыми простыми подзапросами сделать Проверьте все варианты на большой базе и с большим набором слов в одном случае мы имеем один COUNT, в другом 20 джойнов с отдельным поиском по каждой подключенной таблице, первый вариант однозначно будет быстрее и даже в разы. Если на большой таблице COUNT будет работать медленно то поиск по 20 таких же больших таблицах будет в разы медленнее. Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 (змінено) SELECT `tq`.`id` FROM (SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id`) AS `tq` WHERE `tq`.`count` = 2 где 2 - суммарное количество искомых слов.да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; P.S. да, @nikifalex уже давал выше почти такой же вариант. Змінено 21 липня 2016 користувачем sv2109 Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich × Уже зареєстровані? Ввійти Реєстрація Ваші замовлення Назад Придбані модулі та шаблони Ваші рахунки Лист очікувань Альтернативні контакти Форум Новини ocStore Назад Офіційний сайт Демо ocStore 3.0.3.2 Демо ocStore 2.3.0.2.4 Завантажити ocStore Документація Історія версій ocStore Блоги Модулі Шаблони Назад Безкоштовні шаблони Платні шаблони Де купувати модулі? Послуги FAQ OpenCart.Pro Назад Демо Купити Порівняння × Створити... Important Information На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність. Я даю згоду
markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: SELECT `id` FROM `test` WHERE `word` IN ('foo', 'baz') GROUP BY `id` HAVING COUNT(*) = 2; HAVING тоже мега тормоз Я выше писал - UNION еще можно использовать Так как "пара" быстрых ПРОСТЫХ запросов объединенных могут быть во много раз быстрее учитывая что таблица будет в кеше сервера Надіслати Поділитися на інших сайтах More sharing options... markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос Покупцям Оплата розширень фізичними особами Оплата розширень юридичними особами Політика повернень Розробникам Регламент розміщення розширень Регламент продажу та підтримки розширень Віртуальний обліковий запис автора Політика просування оголошень API каталогу розширень Вирішення спорів щодо авторських прав Корисна інформація Публічна оферта Політика повернень Політика конфіденційності Платіжна політика Політика передачі особистих даних Політика прозорості Останні розширення Повний пакет SEO Автор: GeekoDev SameSite Session Fix Opencart 3 Автор: web_bond SP Telegram повідомлення FREE Автор: spectre Відключити порожні категорії Автор: spectre SEO Автор тексту категорії / фільтра / блогу з датою оновлення контенту + мікророзмітка Автор: radaevich
markimax Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 Когда то у меня была похожая задача (давно) и после тестирования на больших базах я остановился на простых запросах обьедененных UNION LJ, HAVING, COUNT - это мега тормоза Надіслати Поділитися на інших сайтах More sharing options... ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку Последние темы Последние дополнения Последние новости Вся активність Головна Підтримка та відповіді на запитання. Допомога програмістам та розробникам Простой SQL запрос
ZeroHero Опубліковано: 21 липня 2016 Share Опубліковано: 21 липня 2016 да, можно еще упростить: Нужно тестить, что будет быстрее на реальной базе. Вполне возможно, что COUNT в SELECT будет быстрее, чем COUNT в HEAVING. SELECT COUNT(*) AS `count`, `id` FROM `test` WHERE `word` IN ('foo', 'bar') GROUP BY `id` HAVING `count` = 2 Надіслати Поділитися на інших сайтах More sharing options...
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 UNION не спасает, потому что он просто объединяет выборки и, если я правильно понимаю, работает по логике "ИЛИ", запрос SELECT t.id FROM `test` t WHERE t.word = 'bar' UNION SELECT t.id FROM `test` t WHERE t.word = 'foo' GROUP BY t.id находит 1,2,3, как и запросы с "OR" или "IN()" Надіслати Поділитися на інших сайтах More sharing options... sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0 Перейти до списку тем Зараз на сторінці 0 користувачів Ні користувачів, які переглядиють цю сторінку
sv2109 Опубліковано: 21 липня 2016 Автор Share Опубліковано: 21 липня 2016 Подведу итоги. Проверил на реальной базе с 42 тыс. записей все варианты запросов. Запросы проверял с "SQL_NO_CACHE", каждый выполнял около десяти раз, брал наименьшее и наибольшее значение, после чего считал среднее. Самыми быстрыми оказались 2 запроса 1. с логикой "OR", оно и не удивительно, но этот запрос не подходит под задание, так как нужна логика "AND" 2. запрос с "HAVING COUNT(*) = 2", который практически вообще не отличается по скорости от обычного запроса с "OR" Поэтому все возражения, о том, что и "HAVING" и "COUNT (*)" являются ну просто очень медленными оказались вообще безосновательными по крайней мене для данной задачи. Наверное потому, что MySQL очень умная, и она не считает "COUNT(*) " для всех записей, а только для найденных согласно других условий, а из 42 тыс. записей найтись могут напр. 50 (или даже меньше), а посчитать к-во для даже 50-ти записей для базы дело тысячной доли секунды, поэтому результат практически не отличается от обычного запроса с "OR" 3. Процентов на 20 медленнее от п. 1-2 работает запрос с вложенным подзапросом 4. Раза в 2 медленнее от п. 1-2 работает запрос с джойнами 5. Запрос с UNION не проверял, так как так и не понял как с помощью него можно решить задачу. Надіслати Поділитися на інших сайтах More sharing options... Створіть аккаунт або увійдіть для коментування Ви повинні бути користувачем, щоб залишити коментар Створити обліковий запис Зареєструйтеся для отримання облікового запису. Це просто! Зареєструвати аккаунт Вхід Уже зареєстровані? Увійдіть тут. Вхід зараз Share More sharing options... Передплатники 0
Recommended Posts