Задать вопрос
  • Почему Float PHP некорректно обрабатывает разряды выше E+15?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    PHP реализует float как IEEE 754 платформозависимого формата.

    То есть в большинстве случаев есть 53 бита мантиссы, что где-то 14-16 значащих десятичных цифр (надо перечитывать стандарт, там ещё nan, infinite кодируется, не очень помню сколько бит непосредственно значение и в каких случаях). Просить из этого достать 20 цифр конечно можно и любой результат с одинаковыми первыми 53 битами будет абсолютно корректен. Потому что float by design приблизительное число.
    Ответ написан
    3 комментария
  • Почему LONG странно себя ведет?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Рассматриваем 64 битное число, big endian byte order в hex представлении записанном как CCD044A12FDB3E13
    В linux php x64 реализует целочисленный int как 64 битовое знаковое число независимо от версии интерпретатора - соответственно подходит.

    Согласно синтаксису PHP шестнадцатеричная запись числа является беззнаковой, знак указывается явно. Число CC больше 7F - следовательно, в знаковом типе недостаточно разрядов (в int есть 63 разряда + бит знака, а требуется минимум 64 + знак) и число приводится к float
    Если вы возьмёте 0x7cd044a12fdb3e13 - это число укладывается в 63 разряда + знак и будет помещено в int тип данных.

    Если у вас машинное представление числа и его необходимо корректно разобрать - есть unpack:
    var_dump(unpack('J', "\xCC\xD0\x44\xA1\x2F\xDB\x3E\x13")[1]);

    Что даст искомый int(-3688372635733115373)
    Плюс внимание на порядок байт. Что unpack позволяет учитывать.
    Ответ написан
    2 комментария
  • Как организовать хранение котировок валют в БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    https://en.wikipedia.org/wiki/Time_series_database

    Писать 1000 строк в секунду mysql может. Читать месячный график (2,5млн точек для одной только котировки) может быть весьма накладно
    Ответ написан
    Комментировать
  • MySQL как работает сравнение строк?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Где-то это было описано... Хм. А, вот
    All MySQL collations are of type PAD SPACE. This means that all CHAR, VARCHAR, and TEXT values are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant.

    Для char, varchar и text оператором сравнения не учитываются пробелы справа и считается что их нет. LIKE - учитывает.
    Ответ написан
    Комментировать
  • Возможно ли оптимизировать структуру таблицы Mysql через сортировку?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    mysql/innodb всегда кластеризована по первичному ключу. Т.е. данные физически упорядочены в порядке задаваемом первичным ключом. Собственно данные и лежат в листьях первичного ключа.

    postgresql умеет команду cluster которая одноразово переписывает таблицу в порядке указанного индекса (плюс внимание на блокировку таблицы на всё время перестроения). В дальнейшей работе пишущих запросов кластеризацию данных не поддерживает.

    Имеет ли кластеризация смысл для вашей задачи - не уверен. Надо смотреть диски и объём горячих данных по отношению к буферной памяти.

    А для графов вероятно лучше взять графовую, а не реляционную СУБД.
    Ответ написан
    1 комментарий
  • Как правильно сделать фильтрацию по числу JSONB в PostgreSQL используя индекс?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Индекс возможно повесить функциональный:
    create index on tablename using btree(((features ->> 'capacity'::text)::integer));

    Соответственно предикат по этому же самому выражению получит возможность использовать этот индекс.

    Больше возможностей внятно индексировать jsonb для запросов на числовые диапазоны мне как-то не вспоминается. Сортировку по полю-то только btree и умеет из всех актуальных access method.

    Т.е. индекс используется, хотя в данном случае index срабатывает на price столбце? Тогда почему запрос отрабатывает быстро?

    Да, индекс используется - индекс по price. Потому что вы по нему сортируете. И планировщик опираясь на свою статистику надеется, что сможет быстро найти 25 строк читая строки в порядке требуемой сортировки по индексу и по пути проверять выкидывать неподходящие.
    Ответ написан
    2 комментария
  • Как правильно составить запрос для взятия первого значения из группы?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Ну а когда станет скучно перебирать всю таблицу - обращайтесь :-)

    Postgresql 9.4 и выше, выбор по известному диапазону дат через index scan по timestamp полю:
    select day, data 
    from generate_series('2017-12-10', '2017-12-12', interval '1 day') as day, 
    lateral (
        select data from tablename 
        where "timestamp" between day and day + interval '1 day' 
        order by "timestamp" desc limit 1
    ) ljd;


    Все дни из таблицы по индексу:
    with recursive t as (
    (select "timestamp"::date as day, data from tablename order by "timestamp" desc limit 1)
    union all
    select bpt.* from t, lateral (
    select "timestamp"::date as day, data from tablename where "timestamp" < t.day order by "timestamp" desc limit 1
    ) as bpt
    )
    select * from t;

    Используя loose index scan
    Ответ написан
    7 комментариев
  • Как искать в моделях yii2 с использованием DATE_FORMAT?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Потому что не надо так искать год. Ваш запрос ведёт к сканированию всей таблицы, либо, в лучшем случае - к необходимости делать отдельный функциональный индекс по этому выражению.
    Сделайте запрос на диапазон
    date_label >= '1994-01-01' and date_label < '1995-01-01'


    Видимо как-то вот так:
    ModelName::find()->where(['between', 'date_label', '1994-01-01', '1995-01-01' ]);
    Ответ написан
    1 комментарий
  • Почему не находит php7.1-mysql_7.1.12?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Открываем ppa.launchpad.net/ondrej/php/ubuntu/pool/main/p/php7.1 и смотрим, что там есть.
    Там есть
    php7.1-mysql_7.1.12-2+ubuntu17.10.1+deb.sury.org+2_amd64.deb

    А вы хотите получить:
    php7.1-mysql_7.1.12-1+ubuntu17.10.1+deb.sury.org+1_amd64.deb

    Следовательно, вы не выполнили обновление списков пакетов в репозиториях и таким образом пытаетесь получить старую версию пакета, уже удалённую.
    Необходимо сделать apt-get update, aptitude update, apt update - смотря чем пользуетесь.
    Ответ написан
    2 комментария
  • Как оптимизировать sql запрос с несколькими Join-ами в ActiveQuery Yii2?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    disabled и date_added - в таблице announcements

    Так нафига вам вообще любой из указанных join'ов равно как и distinct?!
    Вы из них абсолютно никак не читаете и не используете. Так зачем? Просто размножить строки и героически их склеить обратно distinct'ом?

    SELECT `announcements`.* FROM `announcements` 
    WHERE `disabled` = 0 
    ORDER BY `date_added` DESC 
    LIMIT 15
    Ответ написан
  • Как в PostgreSQL выбрать значения значения которые есть в массиве, но нет в БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Всё просто: надо развернуть массив в набор строк и проверить на not exists
    select i from unnest(array[1,2,3,4]) as i 
    where not exists (select 1 from tablename where id = i);
    Ответ написан
    9 комментариев
  • Как подсчитать кол-во вставленных записей в БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Мне неизвестны штатные средства для этого.

    В качестве обходных фокусов можно поизвращаться вот так:
    with 
    data (new_user_id, new_name) as (values(%(user_id)s, %(name)s)),
    wr as (
        INSERT INTO users(user_id, name)
                    select new_user_id, new_name from data
                    ON CONFLICT (user_id) DO NOTHING returning user_id
    ), upd as (
        update users set name = new_name from data where users.user_id = data.new_user_id and data.new_user_id not in (
        select user_id from wr
        )
    )
    select count(*) from wr;


    Что работает согласно задаче из-за того, что do nothing не осуществляет insert и потому строка не появляется в returning.
    Ответ написан
    Комментировать
  • Стоит ли хранить файлы транзакций отдельно от баз?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Имеются в виду pg_xlog (pg_wal в 10) или pg_clog (pg_xact)? Файлы (метаданных) транзакций - это вторые и пишутся они не очень интенсивно. Первый - write ahead log - журнал записи, где отражается вся пишущая активность базы и обычно синхронной записью.

    Производительность дисков для записи WAL - это ключевой фактор для времени commit. Но WAL пишется последовательно и за счёт этого можно держать вполне хорошую нагрузку размещая их монопольно на отдельных HDD, а не SSD. Сэкономив соответственно немного денег на требуемой под базу ёмкости SSD.
    Ну или если у вас записи достаточно много при нормально настроенных checkpointer и bgwriter, чтобы была необходимость выделить отдельные несколько SSD под WAL. Впрочем, у вас в тегах NTFS упомянут. На таком нормальный production всё равно не делают, значит не ваш случай.

    Массивы - RAID10 или RAID1 смотря сколько дисков есть. Для тестовых машин смотрите сами.
    Ответ написан
  • Как случайно выбирать математическое действие?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Различие только в +0, +$D или -$D?
    $array_col2[$i] = ($array_col1[$i] + $D * mt_rand(-1,1));

    Вот и вся логика.
    Ответ написан
    1 комментарий
  • Как быть с CURLOPT_POSTFIELDS и file_get_contents?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_INFILE, fopen('pathtofile', 'rb'));

    Должно быть то что нужно.
    Ответ написан
    2 комментария
  • Вставка записи в главную таблицу и подчиненные?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Добавить ещё один CTE.
    WITH new_tbl_main( id ) AS (
              INSERT INTO tbl_main ( institution_id ) VALUES ( 38)
                RETURNING id 
    ), chi2 as (
    INSERT INTO tbl_child1 ( tbl_main_id ) 
                SELECT new_tbl_main.id  FROM new_tbl_main
    )
    INSERT INTO tbl_child1 ( tbl_main_id ) 
                SELECT new_tbl_main.id  FROM new_tbl_main
                RETURNING tbl_main_id

    Если нужен returning от всех - то добавить ещё cte и в финале склеить запросы через union all или join или как понравится.
    Ответ написан
    Комментировать
  • Как правильно создать функцию возвращающую булевый результат выполнения селекта?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Вероятно при упрощении примера вы выкинули собственно саму причину синтаксической ошибки.
    Потому что приведённая в вопросе хранимка синтаксически корректна, что, впрочем, не изменяет некорректности семантической.
    ERROR: cannot use RETURN QUERY in a non-SETOF function

    Вы не можете использовать return query для возврата одного значений. return query только для функций возвращающих множество. Булево выражение можно посчитать непосредственно в return, как в большинстве других языков:
    CREATE OR REPLACE FUNCTION checkPermission(text, text) RETURNS BOOLEAN AS
    $$
    BEGIN
      RETURN $1 && $2;
    END;
    $$ LANGUAGE plpgsql


    Ну и мелочь лучше записывать на language sql, что позволяет оптимизаторы делать интересные фокусы в целях повышения производительности запросов.
    CREATE OR REPLACE FUNCTION checkPermission(text, text) RETURNS BOOLEAN AS
    $$
      SELECT $1 && $2;
    $$ LANGUAGE sql


    Разумеется, это будет работать только если у вас определён оператор && для пары операндов типа text.
    Ответ написан
    Комментировать
  • Как правильно найти пересечение двух jsonb массивов в postgres?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Есть у постгреса оператор &&

    "есть оператор" - это сказано немного сильно преждевременно. Например, на моей тестовой 9.6 таких операторов 8 штук.
    Потому что нет отдельно операторов. Операторы определены только неразрывно с типами данных своих операндов (двух или одного для префиксных и постфиксных операторов)

    select oprkind, l.typname, oprname, r.typname from pg_operator join pg_type l on oprleft = l.oid join pg_type r on oprright = r.oid where oprname = '&&';
     oprkind |  typname  | oprname |  typname  
    ---------+-----------+---------+-----------
     b       | box       | &&      | box
     b       | polygon   | &&      | polygon
     b       | tinterval | &&      | tinterval
     b       | circle    | &&      | circle
     b       | inet      | &&      | inet
     b       | tsquery   | &&      | tsquery
     b       | anyarray  | &&      | anyarray
     b       | anyrange  | &&      | anyrange

    И jsonb здесь явно отсутствует.

    Значит берём CREATE OPERATOR в руки, пара хранимок - и вот у вас новый оператор готов. Это PostgreSQL, он так умеет и позволяет делать.

    Плюс посмотреть в релевантный jsonb раздел документации: https://www.postgresql.org/docs/current/static/fun...
    Но с операциями на массивами в json там немного печально и неудобно.
    Ответ написан
    Комментировать
  • Как посмотреть, что занимает место на диске linux?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Вероятно запущенные процессы удерживают открытыми дескрипторы уже удалённых файлов, что не позволяет освободить занятое место ФС.

    Список дескрипторов и процессов можно получить например так:
    sudo lsof -a +L1
    Пример строки от меня:
    COMMAND     PID   USER   FD   TYPE DEVICE   SIZE/OFF NLINK    NODE NAME
    php       17455 melkij    4r   REG  254,1 1048576000     0 2624572 /home/melkij/tmpfile (deleted)

    php процесс с pid 17455 удерживает deleted дескриптор файла размером в 1гб.

    Далее адресно разбираться с процессами.
    Ответ написан
    3 комментария
  • Как использовать huge pages для Postgres запущенного в docker контейнере?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Не извращаться и вытащить production базу из докера на нативное железо. Что базе в этом докере делать, если и диск и сеть надо использовать хоста?

    Насколько я помню, ни cgroups ни namespaces не мешают выделенным huge pages. Попробуйте вкрутить vm.nr_hugepages на хост системе и стартовать базу с huge_pages=on
    Ответ написан
    Комментировать