Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Mysql. Много данных. Нужна оптимизация [2]
Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011 Откуда: Одесса, Украина
Помог: 131 раз(а)
фигня какая-то происходит
запросы возвращают 0
при этом именно этот запрос
Мелкий пишет:
Как себя ведёт запрос
CODE (SQL):
скопировать код в буфер обмена
SELECT count(0)
FROM `apple_store_top` `t`
WHERE (platform="1")
AND (appId=:ycp0) AND (country=:ycp1) AND (category=:ycp2)
выполняется быстро и говорит 0
а чуть проще
говорит так
PARTITION BY HASH (( YEAR(`created`)*100+ MONTH(`created`))) PARTITIONS 96
(Добавление)
нашлась причина, просчитался я с размером поля для appId. mediumint мне не хватило и тут пошли жалобы
Message: Out of range value for column 'appId' at row 1
----- Just do it
Мелкий
Отправлено: 22 Октября, 2014 - 17:08:40
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Да, что-то не то.
Там должна быть портянка вроде такой:
/*!50100 PARTITION BY RANGE ( EXTRACT(YEAR_MONTH FROM `date`))
(PARTITION p201401 VALUES LESS THAN (201401) ENGINE = InnoDB,
PARTITION p201402 VALUES LESS THAN (201402) ENGINE = InnoDB,
PARTITION p201403 VALUES LESS THAN (201403) ENGINE = InnoDB,
-- и так насколько вас хватит, лет на 10-20 вперёд
PARTITION pMAXVALUE VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
Но сначала характер нагрузки. Быть может, вам надо партицировать не по дате, а по другим признакам. Что надо чаще получать? Вернее, по какому признаку можно отсекать больше всего данных?
Васин друган пишет:
память все же там не настолько критична как скорость дисков
Верно, не критична. Но больше памяти - меньше требуется от дисков.
----- PostgreSQL DBA
Васин друган
Отправлено: 22 Октября, 2014 - 17:10:17
Новичок
Покинул форум
Сообщений всего: 8
Дата рег-ции: Окт. 2014
Помог: 0 раз(а)
Panoptik пишет:
DATE_FORMAT(created, "%Y.%m.%d%H:00") created
вот это бы убрать бы, лучше потом сверху обернуть. субд не надо тратиться на преобразование в длинных таблицах
Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011 Откуда: Одесса, Украина
Помог: 131 раз(а)
уберу, но не думаю что проблема в этом, раньше нормально работало. короче сейчас данные я запорол, нужно ждать пока отбекапится. завтра буду продолжать колдовать (Добавление)
Мелкий пишет:
Но сначала характер нагрузки. Быть может, вам надо партицировать не по дате, а по другим признакам. Что надо чаще получать? Вернее, по какому признаку можно отсекать больше всего данных?
пока данные выбираются все, это примерно за 3-4 недели, но в запросах предполагается выборка за последних 30 дней в основном, так что думаю что партицирование по дате будет справедливо (Добавление)
Васин друган пишет:
прошу прощения, что встреваю. предыдущие подсказки (Мелкий) абсолютно верны. судя по условиям, основная нагрузка идет по полю криетед. проиндексировав его Вы должны почувствовать разницу. и кантри я бы убрал в отдельную таблицу и вязал бы через айдишники, исключив строковую обработку полей. country in ['aa','bb','ss'] - не хорошо. другое дело насколько проблематично будет перелопатить коды приложения, если они уже привязаны к структуре имеющейся.
и третье, периодическое развертывание бэкапа - тоже будет полезно, файлы бд будут более монолитнее.
приложение пока только строится, так что все уже переделал под внешние таблицы и числовые значения
Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011 Откуда: Одесса, Украина
Помог: 131 раз(а)
вряд ли, оптимизатор делает в фоне много преобразований и подбирает условия как ему удобнее
----- Just do it
MiksIr
Отправлено: 22 Октября, 2014 - 18:46:38
Забанен
Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014
Помог: 10 раз(а)
[+]
Васин друган пишет:
что касается ресурсов сервера бд, память все же там не настолько критична как скорость дисков. на своей шкуре почувствовал (оракл порядка 300 млн записей).
Ну так партицирование как раз и позволяет решить этот вопрос с дисками.
----- self-banned
Васин друган
Отправлено: 23 Октября, 2014 - 06:25:02
Новичок
Покинул форум
Сообщений всего: 8
Дата рег-ции: Окт. 2014
Помог: 0 раз(а)
ну, тогда вот честно - что-то не догоняю. не спорю, секционирование ранжирование никто не отменял.
а память? Имеется в виду кэширование результатов запросов? или ? .. дальше боюсь сморозить фигню какю-нибудь. смотрю на скрипты, вроде ничего военного не вижу.
Мелкий
Отправлено: 23 Октября, 2014 - 10:07:35
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Васин друган пишет:
а память? Имеется в виду кэширование результатов запросов? или ?
Это относится вот сюда, правильно понимаю?
Мелкий пишет:
Верно, не критична. Но больше памяти - меньше требуется от дисков.
Память, любое количество памяти, утилизируется под кэш данных и индексов. Кеширование результатов - это могли додуматься только в mysql. У нормальных БД - кэширование плана запроса после оптимизатора (который далеко не за бесплатно работает).
Данные живут в: кеш непосредственно СУБД (очень быстрый и дешёвый), затем кэш страниц операционной системы (чуть медленнее, но тоже дешёвый) и потом обращение к дискам (очень медленно и очень дорого)
Оперировать СУБД может только с данными, размещёнными в собственном кэше. Соответственно, если там нет нужных данных - СУБД просит ОС эти данные прочитать (вот на это "просит" требуется некоторое время, в отличии от собственного кеша, потому не так быстро и дёшево). ОС может вернуть данные из своего кеша или читать с дисков.
Ужасный вариант - в память (имеется в виду кэш СУБД или ОС) не влезают даже индексы, тупой index scan - и тот читает с дисков. Читать с дисков очень дорого, так что ничего хорошего из этого не получится, тормозить будут даже смехотворные запросы по покрывающим индексам на таблицах в никчёмные десятки тысяч строк. Утилизировать на 100% можно любой диск самой незначительной табличкой.
Индексы в памяти, прогрета часть рабочих данных - что-то размещено в памяти, но на весь рабочий набор памяти не хватило - постоянно с дисков вычитываются новые данные, старые вытесняются из памяти. Распространённый вариант. Тут как раз нужно многое от дисков. Зависит от отношения объёма рабочих данных к объёму памяти под кеши, чем больше данных поднято с дисков в кеш - тем меньше требуется читать с дисков.
Отличный вариант - все рабочие данные размещены в памяти, диски только пишут новые данные и очень редко читают (кому-то вдруг исторические данные поглядеть захотелось). А типичная нагрузка веб-приложения - больше 90% чтения, вот от дисков почти ничего особого и не требуется, от них зависит только скорость записи (ну и время на чтение всего этого при старте системы). Вот тут уже реально упереться в CPU, ну или в сеть, т.к. диски не ограничивают производительность чтения.
----- PostgreSQL DBA
Васин друган
Отправлено: 23 Октября, 2014 - 15:55:14
Новичок
Покинул форум
Сообщений всего: 8
Дата рег-ции: Окт. 2014
Помог: 0 раз(а)
вот так просветили! не ожидал. спасибо). но так глубоко мне не добраться. странно, а я почему-то отталкивался от транзакционных систем. еще вчера язык чесался, что не надо такие запросы запускать. и если проект еще не боевой, лучше заранее сагрегировать что-нибудь под олапы кубики.
Stierus
Отправлено: 24 Октября, 2014 - 16:38:24
Рекордсмен по количеству сообщений за 7 дней
Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008 Откуда: Москваль
Помог: 52 раз(а)
i_category_store_top - ненужный ключ, его можно смело удалить
Конструкция
SELECT
appId,
count(appId) cnt,
....
GROUP BY appId,
мне вообще не понятна, что вы хотите при этом получить?
скиньте дамп строк в 100к что бы статистику примерную видеть (Добавление)
GROUP BY DATE_FORMAT(created, "%Y.%m.%d %H:00") Этот запрос сразу отрубает у вас работу с индексами.
Now () в условии из первого запроса убивает всю работу с кэшами
Что бы решить эти проблемы - организуйте доп поле системное, которое будет хранить уже обработанную DATE_FORMAT(created, "%Y.%m.%d %H:00") строку, либо ее хэш (если коллизии для вас не критичны), а из условий уберите now(), заменив их полученными в php готовыми значениями
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.