Ответы пользователя по тегу MySQL
  • Может ли MySQL глючить?

    @rPman
    Я встречал смутно похожие проблемы (когда буквально where like %zzz% выдавал строки в которых не было 'zzz' когда скорее всего из-за ранее повисшей машины была некорректно перезагружена операционная система и были порушены данные в индексах, repair и пересоздание индекса для гарантии проблему решили.

    Не факт что это твой случае, ты бы хотя бы примеры данных и примеры запроса сюда показал, а то бывает люди надеются на то что порядок в не сортированных данных (или сортировка по не уникальному полю) будет постоянным, а это undefined behavior, именно так это и вылезает в редких неуловимых местах.
    Ответ написан
    Комментировать
  • Стоит ли добавлять index для полей таблицы EAV?

    @rPman
    Если нужны сложные индексы, то в EAV модели появляется дополнительная таблица объектов с выделенными полями под нужные атрибуты, наполняемая тригерами, и уже на них настраиваются индексы.

    Скажи, зачем ты выбрал EAV модель? Зачем создал себе проблем?

    В чем проблема каждому атрибуту создать колонку в таблице, сотни колонок никаких особых проблем (главная рекомендация - не делать default value, если в будущем понадобится удалять добавлять колонки), структура отлично кодом модифицируется и анализируется средствами базы данных, и главное гибко организуются многоуровневые индексы, что сложно реализовать на EAV
    Ответ написан
    6 комментариев
  • Как произвести группировку по последовательным повторам mysql?

    @rPman
    Реляционные базы очень плохо работают с порядком в данных, будет заметный оверхед по запросам.

    У тебя должно быть поле, которое позволит определить однозначный порядок записей (дата у тебя не уникальна значит не подходит), например id с полем autoincrement (осторожно, некоторые базы не гарантируют что значения будут гарантированно расти).

    Я бы решал эту задачу, добавлением дополнительного поля - предыдущее значение (например id на предыдущую запись), особенно это легко и логично, если данные попадают в таблицу последовательно и нет изменений типа удаления и обновления дат, т.е. всего что ведет к изменению порядка.

    Если будет такое поле (id таблицы или сразу значение твоей второй колонки), то запрос, выдающий что тебе надо будет очень простым и отрабатывать очень быстро
    select date,val from table where val<>prev_val order by id


    p.s. иначе тебе придется на каждое значение искать его предыдущее вложенным запросом через order by limit или max/min limit что не очень быстро
    select date,val from table x where val<>(select val from table y where y.date<x.date order by id desc limit 1)

    спецы могут посоветовать красивее запрос через left join, я считаю нужно избегать таких случаев когда нужно искать соседнюю запись
    вот посмотри как я решал похожую задачу
    Ответ написан
    1 комментарий
  • Как заполнить таблицу в цикле Mysql?

    @rPman
    Дано:
    product_attr_id - растет непрерывно по 1
    attr_7 - растет по 1 через три
    attr_29 - растет по 1 но через 3 записи (или при превышении 1099) возвращается к 1097

    итого:

    делаем один единый цикл по product_attr_id - for ... step 1
    увеличиваем attr_29 на 1 каждый шаг и проверяем выход за границу >1099 присваиваем 1097, так же в этот момент увеличиваем attr_7 на 1
    Ответ написан
    Комментировать
  • Обновлять базу данными, затирая первые старые данные?

    @rPman
    Это худшая задача для реляционных баз данных, что там будет происходить с foreign_key я вообще молчу, все решаемо но скорости будут не очень

    Если нет связанных таблиц (что логично, твой id на самом деле не идентификатор, не вводи народ в заблуждение и назови по другому) в твоем случае скорее всего можно схитрить, можно key_id считать на лету, т.е. ключевое поле с autoincrement, но назови его по другому, например key_id_orig
    1+key_id_orig-min(key_id_orig)

    но это сработает только если удаление возможно только самой старой записи, если же будут удаления из середины, то порядок придется пересчитывать по другому, через сортировку всей таблицы по key_id_orig и подсчету колонок функцией row_number
    Ответ написан
    5 комментариев
  • Как по вашему мнению рациональнее собрать дисковую систему на сервере?

    @rPman
    Всегда, если есть возможность сделать два меньших массива вместо одного большого - делай два массива.
    тип - под ситуацию и деньги, raid1 и 0 имеют наименьшие накладные расходы на процессор но кушают доступное место на диске

    raid5 из трех дисков вполне возможен, так как используете десктопные ssd-шники, значит за скоростями не гонитесь и вам хватит софтварного mdadm (настоятельно рекомендую его а не встроенные в zfs и btrfs), поэтому 2 x raid5 по 3 диска - ваш выбор.

    p.s. настрой мониторинг бакапы! а при наличии второй машины, master-slave репликацию для базы, как один из инструментов онлайн резервирования (это так приятно запустить базу данных после сбоя в то же мгновение как умрет главный сервер).
    Ответ написан
    Комментировать
  • Как в mysql выбрать ближайшую бОльшую и ближайшую мЕньшую запись из базы в 1 запрос?

    @rPman
    В комментариях тебе уже ответили вариант с order by. Запрос order by и limit очень тяжелый для sql сервера, его очень сложно оптимизировать.

    Есть еще min max но тебе нужны id, значит вложенный запрос по timestamp, не уверен что это будет быстрее (лучше поэкспериментируй)
    select * from xxx where
       timestamp=(select min(timestamp) from xxx where timestamp > ...)
    or timestamp=(select max(timestamp) from xxx where timestamp < ...)
    p.s. я заметил что ничего не сказано про одинаковые значения timestamp в разных записях, если брать limit 1 то будет выбираться случайная запись (точнее 100500 раз одна но в какой то момент другая - undefined behavior), этот запрос выдаст все записи с одинаковыми timestamp

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

    В каких то ситуациях можно очень СИЛЬНО оптимизировать задачу, если есть какое то знание о том как данные записываются в таблицу. Например если известно гарантированное окно времени, в течении которого поступают данные, и их не сильно много можно просто сделать
    select * from xxx
    where timestamp > date - const_interval
      and timestamp < date + const_interval
    а затем уже среди этих данных выбирать по выше определенным алгоритмам или даже на бакэнде

    Если изменений данных значительно меньше запросов на чтение (особенно если модификации не предполагаются и есть только добавления), то можно складывать искомые значения сразу в момент создания записи (добавлять id новой записи в предыдущую, и тут же ее id в новую), делать это можно как тригерами так и на бакэнде, накладных расходов на такую запись мало зато на чтение данные доступны за константное время, максимально быстро
    select p2.*,p3.* from xxx p1
      left join xxx p2 on p1.id=p2.previous_id
      left join xxx p3 on p1.id=p3.next_id
    where p1.timestamp=...
    в данном случае строчка будет одна, данные раскиданы по колонкам p2.* и p3.*

    В каких то ситуациях можно даже завести отдельный сервис, службу, дающую нужный ответ на порядок быстрее чем любой sql (например за счет того что данные хранятся в оперативной памяти), очень часто этим сервисом может стать тот же бакэнд (если это не cgi приложение), дабы не множить сущности, но если речь идет не об одной физической машине а о кластере, то там есть варианты и сложности.
    Ответ написан
    1 комментарий
  • Как работать с большими данными в MySQL или как создать удобную структуры базы данных?

    @rPman
    Да.
    Есть момент, твой объём данных ничтожно мал.

    У хранения данных в базе данных есть два основных подхода - хранить ключ-атрибут-значение, где на атрибут будет отводиться одна строка таблицы, называется eav, и хранение данных в полях, где на один объект отводится одна запись в таблице атрибуты хранятся в колонках.

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

    Второй подход всем хорош и рекомендуется, мало того можно разрабатывать интерфейс приложения с оглядкой на первый способ с возможностью добавления новых атрибутов не как новые записи в базе а как вызов ddl sql модификации таблицу, т.е. добавлять колонки на лету, таким образом получить достоинства eav и скорость аналитики. Недостаток подхода, в общем случае удаление и изменение колонок медленное в базах данных, так как пересоздаётся вся таблица, Но это проблема будет заметна когда объектов сотни тысяч.

    То есть я рекомендую хранить объекты в строках а атрибуты в колонках, даже если их сотни. Старайся отделять разные объекты по разным таблицам.
    Ответ написан
    2 комментария
  • Откуда внезапная нагрузка на сервер?

    @rPman
    Смотри что выполняется в базе show processlist, в идеале профилируй все запросы, смотри какие больше всего времени выполняются, сделать это можно как на стороне приложения (бакэнда), особенно если используется какая то прослойка для базы данных, так и средствами базы данных, гугли mysql slow query log (на самом деле там куча способов проанализировать работу но чаще удобнее это делать со стороны бакэнда)

    Проанализируй самые тормозные запросы, вполне возможно неправильно индексы настроены и таблицы читаются full scan (перестали влезать в кеш).

    С некоторой вероятностью - размер базы дошел до некоторого критического, и индексы перестали влезать в оперативную память, но сами запросы к диску все еще кешируются ОС (причем не гостевой а хост системы)

    Ну и нельзя исключать злонамеренные действия хостера, особенно дешевые реселеры любят понижать скорость работы VPS-ок с целью вынудить перейти на более дорогие тарифы.
    Ответ написан
    Комментировать
  • Как произвести поиск по огромной базе моментально и вывести данные?

    @rPman
    Для запросов, включающих в себя и фильтрацию where и сортировку/групировку, нужны составные индексы (обычно порядок полей в составном индексе рекомендуется сначала поля, которые в условии where, потом те что в group by/order by)

    Опиши модель данных, без конкретики, но важен смысл любых чисел и условий в твоем запросе, в частности меня смущает твое условие first обычно это показывает что что то не так в самом способе хранения и использования данных

    p.s. иногда, когда запросов на чтение сильно больше запросов на запись, логичнее заполнять тригерами искомые данные в кастомной табличке-кеше

    например в твоем случае последняя добавленная запись может быть скопирована на insert/update в дополнительную таблицу (где вообще индексов нет), тогда брать ее от туда будет максимально просто и быстро
    Ответ написан
    Комментировать
  • Почему может тормозить простейший запрос?

    @rPman
    В чем отличия в серверах? количество оперативной памяти? мажорная версия mysql? настройки?
    есть возможность сравнить конфигурации mysql прошлого сервера и нового с помощью SHOW VARIABLES и уже сравнив их на примере каких-нибудь буферов можно что то менять.

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

    Вот посмотри тут как предлагают проверить, влезает ли индекс в память или нет (подправь там условие чтобы твои таблицы были а не все)
    --------------------------------

    Так же предлагаю провести эксперимент, замени SELECT page_id FROM blitz_tasks WHERE stage = 1533 на список значений в константах (1,2,3,4,...), и если это поможет (а должно так как запрос теперь лезет только в одну таблицу и не трогает другие индексы) то будешь дробить свои запросы, избавляясь от вложенностей и нескольких индексов в одном запросе
    Ответ написан
    8 комментариев
  • Как лучше выстроить связи таблиц в бд на основе json файла?

    @rPman
    Json в базе данных хранить имеет смысл только если в процессе жизни структура этих данных не определена, не формализована (т.п. может меняться от объекта к объекту), и в любом случае от этого нужно уходить.

    Случаи, когда можно поступиться со своей ленью и обединять данные в json, это когда части этих данных не мыслимы друг без друга и меняються скорее тоже вместе, отличный пример - настройки подключения к базе данных можно не делать по полям сервер, ИП, логин, пароль, а хранить сразу одной строкой, как то сериализованной, пусть и json. Был пример, когда шел процесс переделки однопроцессорного сервиса на многопроцессорнй кластер и переноса хранения настроек и характеристик заданий из файлов в бд, там json был оправдан, записи фактически олицетворяли файлы.

    Списочные данные, особенно если по ним нужно поиск а на элементы списка где то в других записях ссылаются, однозначно лучше хранить как записи бд и не json.
    Ответ написан
  • Как получить разницу значений по значению ячейки?

    @rPman
    с помощью if или case switch преврати value_remove/add в знак -/+ перед value, теперь делай sum по получившемуся значению и group by по дням (дату в номер дня преврати, например с помощью day_of_year или бери только день, месяц, год .. как тебе удобно)
    Ответ написан
    Комментировать
  • Как законектить драйвер PDO mysql?

    @rPman
    скорее всего php устанавливался вручную готовым пакетом, все .so идут в поставке по умолчанию
    настраивается в php.ini

    вот пример (пути могут другие быть)
    Ответ написан
    Комментировать
  • Как найти схожий текст в Mysql?

    @rPman
    Akina абсолютно прав, но в качестве ответа - одним из простых критериев похожести может быть отличие в количестве символов (известный алгоритм levenstein)
    вот статья с примерами и реализациями на mysql
    для postgres есть штатная реализация но нативные индексы так и не поддерживаются

    p.s. повторюсь, sql базы данных для данной задачи к сожалению не подходит, чтобы это работало быстро потребуется предварительная обработка базы и построение псевдоиндексов
    Ответ написан
    Комментировать
  • Можно ли хранить права пользователей в БД?

    @rPman
    Настоятельно рекомендую уйти от json сериализации (тем более такой в виде массива) и создать табличку, где строки - пользователи (точнее объекты-правообладатели) а колонки - выдаваемые права.

    Дополнять такую табличку просто, создавая колонки можно указать дефолтное значение (типа нет прав) и все обновится автоматически.

    В будущем же это неплохо модифицируется до многоуровневой системы Пользователь, их Группы, Объекты и Роли (как набор прав за ними стоящими) через вьюхи и триггеры. Но лучше сесть подумать и сделать сразу как надо, такие вещи менять потом больно.
    Ответ написан
  • Можно ли каким-то хитрым SQL-запросом сгенерировать и вставить в таблицу 100500 записей, с последовательно возрастающими int или хэшами?

    @rPman
    если количество не велико (точнее разумно) можно симулировать таблицу с возрастающими значениями на основе union и left join

    p.s. это адский быдлокод но я помню делал такую вьюху
    create view digits (a) as select 0 as a union
    select 1 union
    select 2 union
    select 3 union
    select 4 union
    select 5 union
    select 6 union
    select 7 union
    select 8 union
    select 9

    соответственно дальше можно написать такой запрос
    select x.a+y.a*10+z.a*100 from  digits x,digits y,digits z

    количество указаний digits во from в нем определит максимальное количество значений (в данном случае 1000) как степень 10

    Можно создать из этого ее вьюху, и на ее основе уже оперировать степенями 1000

    у тебя будет виртуальная таблица с нужным количеством записей, ты можешь фильтровать их по значению и формировать на ее основе свои insert
    Ответ написан
    Комментировать
  • Как перенести данные из нескольких таблиц в одну?

    @rPman
    последовательно выполнить
    insert into new_table select from old_table
    если в таблице есть foreign key индксы ли другие constraint, которые могут препятствовать простому их копированию, то отключаешь их перед копированием (для innodb придется удалять и позже создавать заново, для myisam есть метод alter table ... disable keys)
    Ответ написан
    1 комментарий
  • Есть ли разница для скорости работы БД при установке типа text, а не varchar 128?

    @rPman
    varchar/text/bytea в postgres используют одну и ту же технологию хранения и производительность будет напрямую зависеть от реального размера строк и от оптимизаций
    https://habr.com/ru/company/tensor/blog/498292/
    Ответ написан
    Комментировать
  • Реализация автоматического обновления БД?

    @rPman
    я делал (в качестве эксперимента) с помощью создания копии базы через репликацию и опционально снапшоты виртуальной машины.

    Боевая база данных в режиме master, резервная копия (запускаемая в виртуальной машине) настроена в репликацию к базовой в режиме slave, в необходимый момент резервная останавливается, берется копия файлов базы либо создается снапшот файловой системы или средствами виртуальной машины, база данных для резервной копии снова запускается (вместо остановки можно приостанавливать репликацию но это не так красиво) и паралельно запускается снапшот для тестовых задач, по окончанию этих тестов снапшот удаляется.

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

    Кстати снапшоты виртуальной машины позволяют делать копию запущенного приложения (на основе этого реализована миграция, вручную это можно сделать на kvm), правда запускать эту копию придется в отдельной сети, так как ip адрес у нее будет совпадать с оригиналом.
    Ответ написан