Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / 2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы. / 11 сообщений из 11, страница 1 из 1
04.12.2018, 22:31
    #39742592
Dmitriy-CoDy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Есть небольшая табличка примерно 2кк записей.
Делаю запрос следующего формата:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT `id`, `asin`, `marketplace_id`
FROM `repricing_product`
WHERE
  (`marketplace_id` = 10 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  2 AND `asin` IN ('value',.....)) OR   
  (`marketplace_id` =  3 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  1 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  7 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  8 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  5 AND `asin` IN ('value',.....)) OR 
  (`marketplace_id` =  4 AND `asin` IN ('value',.....))



где количество значений в операторе IN достаточно велико (например, в условии с `marketplace_id` = 10 их более 9к).
Результирующая выборка не содержит данные, которые соответствуют условию запроса.

Как показал explain, при выполнении запроса используется составной индекс по полям `asin` и `marketplace_id`.
Переписал запрос на такой:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT `id`, `asin`, `marketplace_id`
FROM `repricing_product`
WHERE
  (`asin`, `marketplace_id`) IN
  (
    ('value',10),....,
    ('value',2),....,
    ('value',3),....,
    ('value',1),....,
    ('value',7),....,
    ('value',8),....,
    ('value',5),....,
    ('value',4),....
  )



При выполнении этого запроса возвращаются все данные.

В итоге получается, что есть 2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса, которые на одинаковых данных возвращают разные результаты.

Из-за "толстого" оператора IN запрос достаточно тяжелый, но он не превышает лимит заданный в конфиге max_allowed_packet. Об ограничениях на количество значений в операторе IN в доках не пишут.
Удалось воспроизвести такое поведение на версиях: 5.6.35-log, 5.6.33-log, 5.6.39-83.1. Тут https://drive.google.com/open?id=11YK9vmLylDRxrMvec-3f3SgI3kq0dR_0 можно скачать дамп БД (одна таблица) и полные версии запросов с комментариями.

Что делал.

Менял порядок шествия значений в операторах IN - набор отсутствующих строк не менялся.
Если менять местами группы условий, разделенные оператором OR - результаты меняются. На это можно посмотреть если поменять местами (`marketplace_id` = 3 AND `asin` IN ('value',.....)) и (`marketplace_id` = 2 AND `asin` IN ('value',.....)) в примере запроса в файле.
Уменьшал количество значений в операторах IN - запрос возвращал правильный результат.

Помогите, плиз, понять в чем проблема и куда копать, чтобы не напороться на поведение как в первом запросе.
...
Рейтинг: 0 / 0
04.12.2018, 23:40
    #39742600
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDy,

покажите полный DDL таблицы
...
Рейтинг: 0 / 0
05.12.2018, 05:31
    #39742633
Dmitriy-CoDy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
miksoftDmitriy-CoDy,

покажите полный DDL таблицы

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE `repricing_product` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `asin` char(10) NOT NULL,
  `marketplace_id` tinyint(3) unsigned NOT NULL,
  `create_date` datetime DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_asin_marketplace_id` (`asin`,`marketplace_id`),
  KEY `idx_marketplace_id` (`marketplace_id`),
  CONSTRAINT `repricing_product_ibfk_1` FOREIGN KEY (`marketplace_id`) REFERENCES `repricing_marketplace` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9141910 DEFAULT CHARSET=utf8 AVG_ROW_LENGTH=55
...
Рейтинг: 0 / 0
05.12.2018, 07:38
    #39742648
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDyгде количество значений в операторе IN достаточно великоВсе значения в IN являются строковыми литералами?
...
Рейтинг: 0 / 0
05.12.2018, 07:40
    #39742649
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDy
Код: sql
1.
`id` mediumint(8) unsigned

Код: sql
1.
AUTO_INCREMENT=9141910

К теме не относится, но обратите внимание, что более половины диапазона значений вы уже использовали.
...
Рейтинг: 0 / 0
05.12.2018, 10:22
    #39742709
Dmitriy-CoDy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
miksoftDmitriy-CoDyгде количество значений в операторе IN достаточно великоВсе значения в IN являются строковыми литералами?

Все значения в операторе IN закавычены. Пример значений: '0001374354','B003G53VSO'.
...
Рейтинг: 0 / 0
05.12.2018, 10:37
    #39742713
paver
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDyВ итоге получается, что есть 2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса, которые на одинаковых данных возвращают разные результаты.

Валидны и эквивалентны они только с ваших слов. Из примера не следует
...
Рейтинг: 0 / 0
05.12.2018, 11:09
    #39742728
Dmitriy-CoDy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
paverDmitriy-CoDyВ итоге получается, что есть 2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса, которые на одинаковых данных возвращают разные результаты.

Валидны и эквивалентны они только с ваших слов. Из примера не следует

Почему? Где я ошибаюсь? Исходя из скрипта ниже, они все-таки эквивалентны и валидны.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
CREATE TEMPORARY TABLE `product` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `asin` char(10) NOT NULL,
  `marketplace_id` tinyint(3) unsigned NOT NULL,
  `create_date` datetime DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_asin_marketplace_id` (`asin`,`marketplace_id`),
  KEY `idx_marketplace_id` (`marketplace_id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `product` (id, asin, marketplace_id)
VALUES
  (7799199, '0001374354', 10),
  (8943063, '0001712713', 10),
  (6030237, '0001839225', 2),
  (8421613, '0002110385', 2),
  (4599181, '000330230X', 3),
  (4395135, '0006176666', 1),
  (3383439, '0006371949', 5),
  (4395273, '0006514391', 1),
  (3383519, '0007103077', 5),
  (6861881, '0007103077', 7),
  (6248157, '0007106777', 8),
  (4599443, '0007115164', 3),
  (3261315, '0007185928', 8),
  (6862551, '000719031X', 7),
  (8478771, 'B003G53VSO', 4),
  (8478379, 'B004DK434C', 4);



SELECT `id`, `asin`, `marketplace_id`
FROM `product`
WHERE
  (`marketplace_id` = 10 AND `asin` IN ('0001374354','0001712713')) OR 
  (`marketplace_id` =  2 AND `asin` IN ('0001839225','0002110385')) OR   
  (`marketplace_id` =  3 AND `asin` IN ('000330230X','0007115164')) OR 
  (`marketplace_id` =  1 AND `asin` IN ('0006176666','0006514391')) OR 
  (`marketplace_id` =  7 AND `asin` IN ('0007103077','000719031X')) OR 
  (`marketplace_id` =  8 AND `asin` IN ('0007106777','0007185928')) OR 
  (`marketplace_id` =  5 AND `asin` IN ('0006371949','0007103077')) OR 
  (`marketplace_id` =  4 AND `asin` IN ('B003G53VSO','B004DK434C'));
  
  
SELECT `id`, `asin`, `marketplace_id`
FROM `product`
WHERE
  (`asin`,`marketplace_id`) IN
  (
    ('0001374354',10),('0001712713',10),
    ('0001839225',2),('0002110385',2),
    ('000330230X',3),('0007115164',3),
    ('0006176666',1),('0006514391',1),
    ('0007103077',7),('000719031X',7),
    ('0007106777',8),('0007185928',8),
    ('0006371949',5),('0007103077',5),
    ('B003G53VSO',4),('B004DK434C',4)
  );
...
Рейтинг: 0 / 0
05.12.2018, 11:15
    #39742731
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
А теперь для показанных двух запросов покажите запись таблицы, которая получается одним из них и не получается другим.
...
Рейтинг: 0 / 0
05.12.2018, 11:19
    #39742735
paver
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDyвозвращают разные результаты.

Игде?
Осталось проанализировать результаты. Выявить те данные, что не попали в первую выборку. Отсюда плясать.
Может опечатка, лишний пробел или что еще.
...
Рейтинг: 0 / 0
05.12.2018, 13:02
    #39742792
Dmitriy-CoDy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы.
Dmitriy-CoDy......
Удалось воспроизвести такое поведение на версиях: 5.6.35-log, 5.6.33-log, 5.6.39-83.1. Тут https://drive.google.com/open?id=11YK9vmLylDRxrMvec-3f3SgI3kq0dR_0 можно скачать дамп БД (одна таблица) и полные версии запросов с комментариями.
......
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / 2 ВАЛИДНЫХ, ЭКВИВАЛЕНТНЫХ запроса возвращают разные результаты. Выборка из одной таблицы. / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]