Ответы пользователя по тегу MySQL
  • Почему получаю ошибку при импорте дампа MySQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    Проверьте версию базы данных.
    utf8mb4 появился только в mysql 5.5.* (емнип, 5.5.3)
    Ответ написан
    Комментировать
  • Как составить такой запрос?

    Melkij
    @Melkij
    PostgreSQL DBA
    select /**/ from products left join files using(id)
    Ответ написан
    Комментировать
  • Mysql размер базы?

    Melkij
    @Melkij
    PostgreSQL DBA
    mysql 4.1?
    Мда. Ищите в архивах минимум 10-летней давности, как тогда можно было считать размер.
    information_schema, помнится, только в 5.0 появился.
    Ответ написан
    Комментировать
  • Почему запрос так долго выполняется?

    Melkij
    @Melkij
    PostgreSQL DBA
    SELECT DISTINCT keywords.id
      FROM keywords
      JOIN images_keywords ON keywords.id = keyword_id
      JOIN images ON image_id = images.id WHERE images.space = 1

    С какой целью вы вообще в этом подзапросе джойните таблицу keywords?
    SELECT DISTINCT keyword_id
      FROM images_keywords
      JOIN images ON image_id = images.id WHERE images.space = 1

    Тот же самый результат будет.

    Вообще, джойн с подзапросом вам и не нужен
    SELECT SQL_NO_CACHE *
    FROM keywords
    WHERE keywords.id IN (
      SELECT DISTINCT keyword_id
      FROM images_keywords
      JOIN images ON image_id = images.id WHERE images.space = 1
    )

    Для mysql актуальных версий in subquery должен работать адекватно.
    Ответ написан
    3 комментария
  • Как сравнить дату в выборке из базы данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    datecolumn >= '2016-02-04' and datecolumn < '2016-02-04' + interval 1 day


    Если кто будет предлагать на первый взгляд более компактное решение date(datecolumn) = '2016-02-04' - сразу учитывайте, что такое условие в mysql в принципе никак не может использовать индексы.
    Ответ написан
    Комментировать
  • Как вставить очень много INSERT за один раз из строк в файле (php)?

    Melkij
    @Melkij
    PostgreSQL DBA
    Сформировать CSV и скормить через LOAD DATA INFILE напрямую в базу.

    Если с load data не получается, то в одной транзакции скармливаете множественные insert'ы (насколько множественные - см max_allowed_packet)
    5 мб данных не так уж и много.
    Ответ написан
    1 комментарий
  • Как добавить значение перед текущим?

    Melkij
    @Melkij
    PostgreSQL DBA
    select concat('dd/', fieldname) ...
    Ответ написан
    Комментировать
  • Как правильно выполнить выборку?

    Melkij
    @Melkij
    PostgreSQL DBA
    select st.name, count(0) from Sms join Sms_status st on status_id = st.id where st.name in ('sent','not_sent', 'new') group by status_id

    Аналогично и первая толпа запросов сворачивается в один простой SQL.

    А с учётом сущности данных - имеет смысл их перенести в отдельную таблицу аггрегации и не пересчитывать в рантайме весь массив.
    Ответ написан
  • Как получить результат update SQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    В mysql - никак. Только дополнительным запросом.
    В том же postgresql - update ... returning
    Ответ написан
    Комментировать
  • Вылетает 500 ошибка?

    Melkij
    @Melkij
    PostgreSQL DBA
    Смотрите в логах конкретику.

    Но конкретно эти запросы имеют одну очевидную проблему: dev.mysql.com/doc/refman/5.6/en/keywords.html
    Ответ написан
    Комментировать
  • Как оптимизировать базу данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    1. Поле типа varchar всегда занимает минимум 1 или 2 байта на диске, в зависимости от максимальной длины этого поля. В индексах и при операциях в памяти разворачивается до своего максимального размера (подобно char). Больше данных -> меньше данных влезает в кеш -> больше нагрузка на диски -> медленнее работа.
    На таком смешном размере таблицы не имеет никакой роли. Если это уже потребовалось оптимизировать - огромные грабли в другом месте.
    2. Да, на диске varchar хранит только то, что положили в поле. Плюс 1 или 2 байта оверхеда на хранению длины записанной строки.
    Ответ написан
    Комментировать
  • Оптимизация группировки SQL запроса?

    Melkij
    @Melkij
    PostgreSQL DBA
    Смотрите в сторону полнотекстового поиска. Начните со штатного в mysql. Если не поможет - используйте сторонний поиск: elastic search, sphinx

    like %что-то% тормозить будет всегда.
    Ответ написан
    1 комментарий
  • Как оптимизировать скорость запроса с использованием индексов MySQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    Нет, отдельный индекс по id_product использоваться не будет. Зачем брать индекс, находить значения по нему и затем искать их по первичному ключу (в innodb кластеризация по первичному ключу же), если можно искать сразу по первичному ключу?
    Вот если бы первичный индекс был id_shop & id_product - тогда да, индекс по id_product был бы полезен.
    Ответ написан
  • Как сделать сложный UPDATE запрос к MySQL для частичного слияния данных двух таблиц?

    Melkij
    @Melkij
    PostgreSQL DBA
    update table2 
    join table1 using(user_id)
     set table2.unicnumber = table1.unicnumber 
    where table1.accept = 1

    ?
    Ответ написан
    Комментировать
  • Есть ли решение для пагинации древовидных комментариев?

    Melkij
    @Melkij
    PostgreSQL DBA
    Начните с изучения вопроса, как можно хранить деревья в РСУБД.
    Для ограниченного количества вложенности - материализованной путь отлично подходит. И элементарно выводится limit'ом, можно даже без offset'а обойтись, если озадачиться.
    Ответ написан
    Комментировать
  • Rак правильно организовать списание баланса?

    Melkij
    @Melkij
    PostgreSQL DBA
    InnoDB все запросы выполняет только в транзакции. Если открытой транзакции не было, то этот запрос неявно оборачивается в транзакцию.
    Вот только сами по себе транзакции не помогут, надо ещё правильно ими пользоваться. Тут я бы хотел дополнительно обратить внимание Андрей:
    Попробуйте в двух терминалах написать:
    сначала begin; в обоих
    потом select из таблички. Значения одинаковые, правда?
    потом update этой же таблички, сделайте set fieldname = разные значения в терминалах. Второй терминал запрос принял, но не вернул управление, верно?
    потом commit; в первом терминале. update из второго терминала сразу же ответил OK.
    Теперь сделайте commit во втором терминале и посмотрите, что произошло с данными. Это то, на что вы рассчитывали? Или всё-таки не совсем?

    N пользователей запрашивают услугу одновременно, корректно ли произойдет списание средств?

    Нет, некорректно, если только вы не в одной транзакции и не читаете баланс специально с select .. for update.
    Потому что для выполнения действия $this->balance -= $sum; у вас уже должен быть известен баланс, но это ещё не операция записи.
    В итоге у вас было 1000 рублей.
    Пришёл один клиент, прочитал баланс, хочет списать 200 рублей. Обновил циферку в PHP, никто ему не мешает.
    Пришёл второй клиент, прочитал баланс, хочет списать 100 рублей. Обновил циферку в PHP, никто ему тоже не мешает.
    И на шаге save оба отправили запросы на update: один клиент считает, что на балансе осталось 800 рублей, второй - что 900.
    Сколько запишется на баланс? 800 или 900, как повезёт. Правильно ли это? Сколько должно было быть? 700 ведь.
    Потому что клиенты не мешали друг другу обновлять циферку в PHP.

    Как же заставить клиентов не делать глупости?
    В простом случае:
    update tablename set balance = balance - :amount where balance >= :amount and user_id=:uid
    И на приложении проверять affected_rows. Если строка изменена - у пользователя достаточно денег, платёж прошёл. Если изменённых строк нет - вероятно, у пользователя нет столько денег. СУБД разберётся с очерёдностью исполнения и в результате на балансе будет правильная сумма, сколько бы параллельных запросов ни пришло. И, что не менее важно - приложение ответит на все запросы корректно, кому денег хватило, а кому - уже нет.

    В более сложных случаях - можно самому попросить СУБД взять блокировку на строку, о чём чуть ранее я уже заикался:
    begin;
    select balance from tablename where user_id=:uid for update; -- все параллельные транзакции будут выстраиваться в очередь здесь
    /* произвольные запросы (в mysql кроме вызова хранимок, DDL - они делают неявный коммит). Среди этих запросов - обновляете баланс */
    commit; -- только здесь эта транзакция освобождает блокировку select .. for update и с этой строкой начинает работать следующий запрос

    Как вообще работать с деньгами и делать это правильно - Кирилл даёт правильное направление. Изучите, как это делает бухгалтерия, за многие десятилетия работы они придумали, как обходить много странных граблей.
    Ответ написан
    2 комментария
  • Как эффективно организовать таблицу для 250 000 записей?

    Melkij
    @Melkij
    PostgreSQL DBA
    Если вам действительно, в реальности, зачем-то нужно делать where value = "4 миллиона знаков", то сделайте hash-индекс.
    Mysql их не умеет, так что велосипедим рядом ещё одним полем, в которое пишете результат хэш-функции от этого самого текста. И индексируем обычным btree. Например, md5 или даже просто crc32
    В запросе, соответственно, where hash = посчитанный хэш and value = "4 миллиона знаков"
    Ответ написан
    2 комментария
  • Как найти цифру через LIKE?

    Melkij
    @Melkij
    PostgreSQL DBA
    Приведите в нормальную форму. Сразу гора костылей пропадёт.
    Ответ написан