SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 30.10.2017 20:06:42

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2101

Быстро определить есть ли n нужных записей

Доброго времени суток, Коллеги!

Поделитесь соображениями по сабжу пожалуйста.

Окружение: Ubuntu 16.04, MySQL 5.7

Исходные данные: есть таблица t, в ней в том числе хранятся адреса address_id и владельцы адресов owner_id.
То есть можно, в частности, почерпнуть информацию - у какого владельца какие адреса.

Записей в таблице, в лучших традициях, больше миллиарда (тип innoDB).
При чем разбиение крайне неравномерное - есть владельцы, у которых миллионы адресов (их мало),
есть владельцы, у которых 1-2 адреса (таких абсолютное большинство).

Иногда нужно быстро определить по нескольким владельцам (допустим для тридцати владельцев):
1) есть ли у него хоть один адрес
2) есть ли у него 10 или больше адресов
3) есть ли у него 100 или больше адресов

Наличие btree-индекса на address_id позволит шустро найти все записи для конкретно взятого владельца, но если их там миллионы - очень не хотелось бы прочитывать все миллионы записей этого владельца,
если нужно лишь удостовериться в том, что у владельца есть, допустим, 10 или 100 адресов (не миллионы, а именно "чуть-чуть").

Смотрел в сторону exists/limit, но ничего хорошего не родилось.

Any ideas?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#2 30.10.2017 21:38:33

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 21.01.2007
Сообщений: 6641

Re: Быстро определить есть ли n нужных записей

EXPLAIN SELECT * FROM t WHERE owner_id = ?
или SELECT COUNT(*), если нужно точное значение. Но есть ощущение, что в твоей задаче достаточно оценки.

Неактивен

 

#3 31.10.2017 11:16:38

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2101

Re: Быстро определить есть ли n нужных записей

EXPLAIN - он ведь может и обмануть sad, неточно же выдаёт значения. Статистика не всегда суперактуальна ведь.

В моей задаче достаточно оценки, но не должно ни в коем случае такого быть, что на конкретного владельца приходит информация, что адресов у него нет, в то время как они есть.

Если я запрашиваю, есть ли у владельцев по 200 адресов, то да - не важно, 300 их или 400 или миллион - важно что 200 есть. Но если меньше 200 - ошибки быть не должно.

Что же до count(*)

SELECT count(*) FROM t WHERE owner_id=АЙДИ_МНОГОМИЛЛИОННО_АДРЕСНОГО_ВЛАДЕЛЬЦА;

- он ведь бежит по всем миллионам строк этого владельца, так этот запрос может и секунду времени занимать, хочется этого избежать - чтобы он нашел нужное количество строк и "угомонился".

Я думал про вариант

SELECT 1 FROM t WHERE owner_id=АЙДИ_МНОГОМИЛЛИОННО_АДРЕСНОГО_ВЛАДЕЛЬЦА limit 200;

по идее он должен выбрать 200 и остановиться, так?

или в случае, если нужно установить есть ли хоть один адрес
SELECT 1 FROM t WHERE owner_id=АЙДИ_МНОГОМИЛЛИОННО_АДРЕСНОГО_ВЛАДЕЛЬЦА limit 1;


Через UNION объединить запрос с к каждому отдельному адресу?

SELECT ID_OWNER1, (SELECT count(*) FROM (SELECT 1 FROM t WHERE owner_id=ID_OWNER1 limit 200) t1 )  >= 200
UNION
SELECT ID_OWNER2, (SELECT count(*) FROM (SELECT 1 FROM t WHERE owner_id=ID_OWNER2 limit 200) t2 )  >= 200
UNION
...
UNION
SELECT ID_OWNERN, (SELECT count(*) FROM (SELECT 1 FROM t WHERE owner_id=ID_OWNERN limit 200) tn )  >= 200
 


Так вроде шуршит, и судя по скорости  - выбирает максимум по 200 штук по каждому адресу и останавливается.

А в  GROUP BY это как-то не засовывается (. Или это и не будет лучшим путем здесь?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#4 31.10.2017 11:25:51

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 21.01.2007
Сообщений: 6641

Re: Быстро определить есть ли n нужных записей

Сгруппировать и правда не сможешь, скорее всего.

COUNT(*) будет считать ключи индекса, что быстрее просмотра строк, но может быть все равно медленным, да.

Про оценку — у меня есть стойкое ощущение, что нужна тебе именно она smile Она умеет оценивать «много», «мало» и ноль (она пытается сделать спуск и сразу увидит, если нет ни одного ключа, удовлетворяющего условию). То есть ответить на вопрос «200» ты оценкой не сможешь, но в изначальной задаче этого не было.

В остальном вариант с лимитом вполне ок.

Неактивен

 

#5 31.10.2017 11:48:37

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2101

Re: Быстро определить есть ли n нужных записей

paulus написал:

Сгруппировать и правда не сможешь, скорее всего.

Похоже на то..

paulus написал:

COUNT(*) будет считать ключи индекса, что быстрее просмотра строк, но может быть все равно медленным, да.

Да, я проверял неоднократно. На владельце с тремя миллионами адресов - секунду запрос работает, это как-то грустновато.

paulus написал:

Про оценку — у меня есть стойкое ощущение, что нужна тебе именно она smile Она умеет оценивать «много», «мало» и ноль (она пытается сделать спуск и сразу увидит, если нет ни одного ключа, удовлетворяющего условию). То есть ответить на вопрос «200» ты оценкой не сможешь, но в изначальной задаче этого не было.

Про оценку - ты имеешь в виду ограничиться explain'ом?
А он точно ответит хотя бы на вопрос  "ноль" или "не ноль"? В частности, в случае, если статистика не самая точная ).


Чаще нужно знать, есть ли вообще хоть один адрес у владельца, но бывает что нужно и про 200 знать. Чесна-чесна smile.
Ну а в случае, если нужно знать про то есть ли хоть один адрес у владельцев -
то, видимо, в моем запросе нужно просто 200 на 1 изменить и будет щастье (если таки не рискну использовать explain).


paulus написал:

В остальном вариант с лимитом вполне ок.

Хочу еще заметить, что с explain'ом я с UNION не смогу выкрутиться - то есть придется на каждого владельца explain отдельный загонять, так ведь?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#6 31.10.2017 11:58:46

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 21.01.2007
Сообщений: 6641

Re: Быстро определить есть ли n нужных записей

У меня есть стойкое ощущение, что ноль будет честной оценкой всегда. Эдакий блум-фильтр.

И да, UNION работать не будет в этом случае sad

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson