На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
  
> Критически долго выполняется запрос
    Всем дратути! )))

    Есть таблица со множеством полей типа:

    ExpandedWrap disabled
      CREATE TABLE big_data
      (
        id serial NOT NULL,
        ...
        is_active boolean NOT NULL,
        source_id integer NOT NULL,
        CONSTRAINT big_data_pkey PRIMARY KEY (id)
      );


    Есть общий индекс btree на is_active и source_id.

    Запрос во вновь созданной таблице на 7 млн. сгенерированных записей

    ExpandedWrap disabled
      SELECT id FROM big_data WHERE is_active IS TRUE AND source_id=2 ORDER BY id DESC LIMIT 1;


    отрабатывает вполне себе шустро, а вот с боевого накатываю 7 млн.записей -- выполняется более получаса и не дает результатов. При этом в логе этот запрос показывается и EXPLAIN-ы (без выполнения) на обоих наборах данных почти одинаковые.

    В чем может быть причина? Или как можно диагностировать проблему?
      Какая СУБД? какая версия сервера? Отдельно на тесте и на продакшене.

      Цитата piksel @
      Есть общий индекс btree на is_active и source_id

      А показать в составе DDL - не?

      Цитата piksel @

      ExpandedWrap disabled
        WHERE is_active IS TRUE


      Это - серьёзно? вот прямо так и в запросе?

      Цитата piksel @
      EXPLAIN-ы (без выполнения) на обоих наборах данных почти одинаковые.

      Почти одинаковые - это РАЗНЫЕ. В студию.
        Да, извиняюсь за неточности первоначального вопроса. Вроде немного проясняется. Всё дело в том, что есть 2 таблицы. Одна с рабочими данными, а другая тестовая для опытов.
        Рабочая:
        ExpandedWrap disabled
          CREATE TABLE public."big_data"
          (
            "id" INTEGER NOT NULL DEFAULT NEXTVAL((pg_get_serial_sequence('"public"."big_data"'::text, 'id'::text))::regclass),
            ...
            source_id SMALLINT,
            is_active BOOLEAN DEFAULT TRUE,
            CONSTRAINT "pbig_data" PRIMARY KEY ("id")
          )
          WITH (
            OIDS=FALSE
          );
          CREATE INDEX "ibig_data-source_id__is_active"
            ON public."big_data"
            USING btree
            (source_id, is_active)
            WHERE source_id IS NOT NULL AND is_active;

        и та на которой я всё тестирую, заполненная примерно таким же количеством данных:
        ExpandedWrap disabled
          CREATE TABLE public.big_data
          (
            id INTEGER NOT NULL DEFAULT NEXTVAL('big_data_id_seq'::regclass),
            text_data text,
            is_active BOOLEAN DEFAULT TRUE,
            source_id SMALLINT,
            CONSTRAINT big_data_pkey PRIMARY KEY (id)
          )
          WITH (
            OIDS=FALSE
          );
          CREATE INDEX big_data_source_id_index
            ON public.big_data
            USING btree
            (source_id, is_active)
            WHERE source_id IS NOT NULL AND is_active;

        Так вот. Один и тот же запрос:
        ExpandedWrap disabled
          EXPLAIN SELECT
              "id"
          FROM
              "big_data"
          WHERE
              source_id = 6
              AND is_active
          ORDER BY "id" DESC
          LIMIT 1

        и
        ExpandedWrap disabled
          EXPLAIN SELECT id FROM big_data WHERE is_active AND source_id=2 ORDER BY id DESC LIMIT 1;

        даёт разные результаты - в одном индекс используется, в другом - нет:
        ExpandedWrap disabled
          "Limit  (cost=0.43..220.64 rows=1 width=4)"
          "  ->  Index Scan Backward using "pbig_data" on "big_data"  (cost=0.43..10254585.72 rows=46567 width=4)"
          "        Filter: (is_active AND (source_id = 6))"

        ExpandedWrap disabled
          "Limit  (cost=11.26..11.26 rows=1 width=4)"
          "  ->  Sort  (cost=11.26..11.26 rows=3 width=4)"
          "        Sort Key: id DESC"
          "        ->  Bitmap Heap Scan on big_data  (cost=4.13..11.24 rows=3 width=4)"
          "              Recheck Cond: ((source_id = 2) AND is_active)"
          "              ->  Bitmap Index Scan on big_data_source_id_index  (cost=0.00..4.13 rows=3 width=0)"
          "                    Index Cond: (source_id = 2)"
        Сообщение отредактировано: piksel -
          Цитата Akina @
          Какая СУБД? какая версия сервера?

          ?
            Возникли три предположения:
            1. Разница потому, что используются разные ид: 2 и 6. Попробовать одинаковые ид;
            2. Статистики неправильные. Обновить статистики;
            3. Запрос на рабочем сервере блокируется другими запросами. Попробуй грязное чтение;
              PostgreSQL 9.6

              В общем, спасибо всем! Проблема решена. Не умею нормально строить индексы. Надо:
              ExpandedWrap disabled
                CREATE INDEX big_data_source_id_index
                  ON public.big_data
                  USING btree
                  (source_id, id)
                  WHERE source_id IS NOT NULL AND is_active;
              Сообщение отредактировано: piksel -
              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script execution time: 0,0643 ]   [ 16 queries used ]   [ Generated: 28.03.24, 13:21 GMT ]