Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Доброго времени суток, Коллеги!
Поделитесь соображениями по сабжу пожалуйста.
Окружение: 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?
Неактивен
EXPLAIN SELECT * FROM t WHERE owner_id = ?
или SELECT COUNT(*), если нужно точное значение. Но есть ощущение, что в твоей задаче достаточно оценки.
Неактивен
EXPLAIN - он ведь может и обмануть , неточно же выдаёт значения. Статистика не всегда суперактуальна ведь.
В моей задаче достаточно оценки, но не должно ни в коем случае такого быть, что на конкретного владельца приходит информация, что адресов у него нет, в то время как они есть.
Если я запрашиваю, есть ли у владельцев по 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 объединить запрос с к каждому отдельному адресу?
Неактивен
Сгруппировать и правда не сможешь, скорее всего.
COUNT(*) будет считать ключи индекса, что быстрее просмотра строк, но может быть все равно медленным, да.
Про оценку — у меня есть стойкое ощущение, что нужна тебе именно она Она умеет оценивать «много», «мало» и ноль (она пытается сделать спуск и сразу увидит, если нет ни одного ключа, удовлетворяющего условию). То есть ответить на вопрос «200» ты оценкой не сможешь, но в изначальной задаче этого не было.
В остальном вариант с лимитом вполне ок.
Неактивен
paulus написал:
Сгруппировать и правда не сможешь, скорее всего.
Похоже на то..
paulus написал:
COUNT(*) будет считать ключи индекса, что быстрее просмотра строк, но может быть все равно медленным, да.
Да, я проверял неоднократно. На владельце с тремя миллионами адресов - секунду запрос работает, это как-то грустновато.
paulus написал:
Про оценку — у меня есть стойкое ощущение, что нужна тебе именно она Она умеет оценивать «много», «мало» и ноль (она пытается сделать спуск и сразу увидит, если нет ни одного ключа, удовлетворяющего условию). То есть ответить на вопрос «200» ты оценкой не сможешь, но в изначальной задаче этого не было.
Про оценку - ты имеешь в виду ограничиться explain'ом?
А он точно ответит хотя бы на вопрос "ноль" или "не ноль"? В частности, в случае, если статистика не самая точная ).
Чаще нужно знать, есть ли вообще хоть один адрес у владельца, но бывает что нужно и про 200 знать. Чесна-чесна .
Ну а в случае, если нужно знать про то есть ли хоть один адрес у владельцев -
то, видимо, в моем запросе нужно просто 200 на 1 изменить и будет щастье (если таки не рискну использовать explain).
paulus написал:
В остальном вариант с лимитом вполне ок.
Хочу еще заметить, что с explain'ом я с UNION не смогу выкрутиться - то есть придется на каждого владельца explain отдельный загонять, так ведь?
Неактивен
У меня есть стойкое ощущение, что ноль будет честной оценкой всегда. Эдакий блум-фильтр.
И да, UNION работать не будет в этом случае
Неактивен
Страниц: 1