Ответы пользователя по тегу MySQL
  • Скопировал таблицу MySQL. Что не так?

    Melkij
    @Melkij
    PostgreSQL DBA
    Всё так. Что сказали сделать, то СУБД и сделала.

    create table as select никак не связано с копированием структуры таблицы. Создаёт новую таблицу, используя в качестве полей результат запроса и затем копирует результат запроса в качестве данных.

    Копирует структуру таблицы включая индексы запрос CREATE TABLE newtable LIKE oldtable;
    Данные не копирует. Можно скопировать через insert .. select.
    Ответ написан
  • Как считается длина ключа в Explain mysql?

    Melkij
    @Melkij
    PostgreSQL DBA
    Давайте считать:
    timestamp - 4 байта
    tinyint по 1 байту
    int - 4 байта
    varchar(255) - где 255 длина в символах. В байтах будет больше. Например, для utf8, потребуется 255*3+2 байта. 767 байт. Для utf8mb4 - 255*4+2
    Итого строка индекса занимает 4 + 767 + 1 + 1 + 4 = 777 байт. Немного не хватает, может быть у вас какие-то из полей могут быть NULL?

    Да, если вы не знали, в индексе и в памяти (например, при сортировке) varchar всегда развёрнут до максимальной длины.
    Если возможные строки у вас фиксированы - используйте enum. 1 или 2 байта места для записи. И уж определённо не 255, если у вас строки в 4-6 символов.
    Ответ написан
    1 комментарий
  • Как получить параметры колонки при выборки данных через SELECT?

    Melkij
    @Melkij
    PostgreSQL DBA
    Приджойнить подходящую вьюху из INFORMATION_SCHEMA. Вроде бы INFORMATION_SCHEMA.COLUMNS должна содержать нужные данные.
    Ответ написан
    1 комментарий
  • Как оптимизировать выборку строк из базы данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    Сгенерируйте и запишите в свою табличку какой-нибудь мелкий объём тестовых данных. Миллионов 10 строк хотя бы. Мелочь какая-то, да хоть будет о чём поговорить.
    Поиграйтесь с этой мелкой табличкой, посмотрите, какие запросы будут выполняться медленно. Затем возвращайтесь с конкретными запросами и explain'ами.
    Ответ написан
    Комментировать
  • Как получить все даты с 01-01-2014 по сегодня с помощью простого mysql-запроса без хранимы процедур?

    Melkij
    @Melkij
    PostgreSQL DBA
    Нельзя.
    Mysql не умеет никакого подобия generate_series. И даже хранимка может лишь вывести список дат. Приджойнить этот список к чему-нибудь другому нельзя.

    К слову, order by 1 - deprecated. "Use of column positions is deprecated because the syntax has been removed from the SQL standard."
    Ответ написан
    Комментировать
  • Ошибка cannot add or update a child row при создании связи между таблицами, как исправить?

    Melkij
    @Melkij
    PostgreSQL DBA
    Существующие в таблицах данные не проходят проверку внешним ключом. Т.е. существуют ссылки на отсутствующие магазины.
    Ответ написан
    1 комментарий
  • Как сформировать sql запрос используя имена столбцов в виде массива?

    Melkij
    @Melkij
    PostgreSQL DBA
    assert('!empty($fieldNames) and is_array($fieldNames)');
    $query = 'set field_name = (' . join(' + ', $fieldNames) . ')/' . count($fieldNames);


    Вероятна ошибка проектирования схемы БД. С учётом использования давным-давно удалённых функций mysql_* вероятность ошибки, а не осмысленного выбора резко увеличивается.
    Ответ написан
    Комментировать
  • Как отсутствие id (int - primary key, auto_increment) поля влияет на скорость работы MySQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    Касательно именно mysql/innodb - innodb всегда кластеризован по первичному ключу. Поэтому все вторичные индексы всегда указывают на первичный ключ. Что из этого следует:
    select time, md5 from img where md5=?
    Потребует просмотра всегда двух индексов. Сначала индекса по md5, потом - первичного ключа.
    С первичным ключом по md5 этот запрос сделает один просмотр индекса и для вычитывания time, не входящего в индекс, даже не потребует seek - данные лежат непосредственно рядом с листьями первичного ключа. Т.е. от выкидывания суррогатного ключа этому запросу чистый профит.

    Не случайно написал time в запросе, если запросить только select md5 или select md5, id - то это будет index only scan по вторичному ключу и сейчас, без обращения ни к первичному ключу ни к самой таблице.

    во-вторых,
    int - это 4 байта. varchar32 для cp1251 (почему вообще varchar, а не char(32) или вообще binary(16)?) - 32 байта, timestamp 4 байта. Из-за необходимости ссылаться на куда более объёмный первичный ключ, резко увеличатся в объёме все вторичные индексы. Но вторичный индекс у вас останется только один, да один индекс исчезнет, а уникальный немного похудеет за счёт преобразования в первичный. Не столь огромный оверхед получится, вполне можно пережить. Но может быть не столь интересно, если показана часть таблицы и есть кучка других полей и индексов.
    Поиск по time чуток просядет, строки сравнивать всё-таки сложнее пары интов. Но на десятке млн записей, да на mysql значения это играть не будет.

    в-третьих, innodb оптимизирован под запись последовательно-возрастающих значений. На записи случайных данных несколько просядет производительность. На сколько именно - надо измерять, не помню.
    На небольшой табличке всего-то в пару десятков миллионов строк - это значения иметь не будет.
    Ответ написан
    3 комментария
  • Тормозит mysql, это кэш?

    Melkij
    @Melkij
    PostgreSQL DBA
    правильно ли я понимаю, что mysql кэширует не сам запрос, а как бы схему его выполнения?

    Нет, mysql как раз кеширует непосредственно результат конкретного запроса.
    План запроса строится заново для каждого запроса, не найденного в query cache.
    query cache может быть и выключен, тогда mysql от запроса не кеширует ни план, ни результат.

    Если запрос выполняется к редкоиспользуемой части данных - значит скорей всего пришлось читать с диска. Это варьируется от медленно до смертельно медленно в зависимости от дисков. Затем данные будут жить в кеше данных mysql (см. тюнинг используемых storage engine) и в кеше операционной системы (плюс в query cache результат запроса), пока не будут оттуда вытеснены другими более нужными данными. Сами индексы тоже могут выгружаться из памяти и даже index only scan может пойти на медленный диск.
    Запрос, которому пришлось лезть на диск и запрос, все данные для которого уже оказались в памяти - две огромные разницы даже для приличных SSD.
    Ответ написан
    Комментировать
  • Почему пропадает значение переменной при подключении к БД?

    Melkij
    @Melkij
    PostgreSQL DBA
    Давно удалённая функция mysql_query попытается сначала найти уже открытое ранее соединение через mysql_connect. Если такого нет - попробует сама установить соединение с дефолтными настройками root@localhost,, без пароля.
    Что в тексте ошибки и видно.
    Ответ написан
    Комментировать
  • SQL вставка текста в столбец перед нативным текстом, можно ли и как?

    Melkij
    @Melkij
    PostgreSQL DBA
    "нативный текст" - это то, что в поле уже есть до выполнения запроса?

    update tablename set img_url = concat('/images/', img_url);
    Ответ написан
    2 комментария
  • Как проверить существование БД?

    Melkij
    @Melkij
    PostgreSQL DBA
    Подключиться и скомандовать
    show databases like 'db_name'
    Будет строка в ответе - значит есть БД. Пусто - значит нет такой.

    Плюс, create database умеет идемпотентное поведение
    CREATE DATABASE IF NOT EXISTS db_name
    dev.mysql.com/doc/refman/5.7/en/create-database.html
    Ответ написан
    3 комментария
  • MySQL: count(*) или table_rows или ...?

    Melkij
    @Melkij
    PostgreSQL DBA
    innodb - это MVCC.
    Чтобы узнать, сколько строк в таблице - нужно узнать, какие версии строк может видеть эта транзакция. Без вычитывания всех подходящий строк ответ не получить. Разумеется, быстро это работать не будет.
    Поэтому данные в information_schema - приблизительная оценка всегда.

    Уменьшайте объём данных. Например, если вы растёте по шкале времени, то стройте аггрегаты по времени заранее. Например, по дням и часам. Текущий час s/вычитывать count'ом/инкрементить в каком-нибудь редисе или мемкеше вместе с insert'ами/g,, потом пересчитывать и сохранять к другим аггрегатам.
    Ответ написан
  • Какой учебник по SQL почитать?

    Melkij
    @Melkij
    PostgreSQL DBA
    Must read по mysql: High Performance MySQL Optimization, Backups, and Replication, Baron Schwartz

    Для теоретических знаний - относительно недавно в реляционных базах принципиально ничего не менялось, как и десятилетие назад. И два десятилетия и может даже три. Фундаментальная теория РСУБД и транзакционных систем - да, из прошлого тысячелетия. За новизной в теории гнаться бессмысленно.
    Другое дело, если вы хотите особенности какой-то определённой СУБД. У каждой ворох своих особенностей, бывают и нарушения стандартов и что-нибудь меняется с каждым релизом. Лучший друг - мануал от корки до корки, книги поздновато выходят. Можно много полезного вычитать.
    Ответ написан
    1 комментарий
  • Как записать иконки в БД?

    Melkij
    @Melkij
    PostgreSQL DBA
    Во-первых, используйте нормальные подготовленные выражения или хотя бы не отключайте эмуляцию в PDO. Ничего они не порежут. Реальные подготовленные выражения пойдут вообще как есть в бинарном виде, эмуляция в PDO сделает всё возможное для корректной передачи.

    Второе - используйте кодировку utf8mb4. Если вы думаете, что utf8 в mysql и utf8 в остальном мире - это одно и то же, то вы ошибаетесь. Во всём мире в utf8 до 4 байт на символ, в mysql - только 3. Вот всякие модные нынче смайлики в этом 4 байте и живут.
    Ответ написан
    1 комментарий
  • Sphinx, как создать конфиг если количество таблиц может изменяться но они однотипные?

    Melkij
    @Melkij
    PostgreSQL DBA
    Сделать одну таблицу клиентов. Если того требуют объёмы в миллиарды строк - партицировать штатными средствами.
    Ответ написан
    1 комментарий
  • Как одним select выбрать максимальную дату в MYSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    Одну строку?
    select info, date from table order by date desc limit 1;

    Если все строки с одинаковой максимальной датой - то да, подзапрос.
    Ответ написан
    Комментировать
  • Как посчитать количество записей за определённый период?

    Melkij
    @Melkij
    PostgreSQL DBA
    select date(`created_at`) as create_date, sum(if(type = 'new', 1,0)) as new_count, sum(if(type = remove, 1,0)) as rm_count
    from actions 
    where user_id = 1 and created_at > DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
    group by create_date


    Ну а если надо часто такую аггрегацию делать - сделайте таблицу с предварительно агрегированными по дням данными.
    Ответ написан
    Комментировать
  • Как сделать SQL (MySQL), который добавить запись, если с момента последней прошёл 1 час?

    Melkij
    @Melkij
    PostgreSQL DBA
    insert into tablename (datetimefield /*other fields*/) 
        select now(), /*other fields*/ 
        from (select 1) anyonerow 
        where not exists(
            select 1 from tablename where datetimefield >= now() - interval 1 hour
        )

    Результат была ли запись добавлена - смотреть в affected_rows.
    Ответ написан
    Комментировать