Ограничительное предложение работает в postgres?

Итак, у меня есть таблица с 1000 строками, я просто говорю select * from hugedata limit 1 план запроса просто говорит table scan затем limit operator прилагается план запроса

    [
  {
    "Plan": {
      "Node Type": "Limit",
      "Parallel Aware": false,
      "Async Capable": false,
      "Startup Cost": 0.00,
      "Total Cost": 0.02,
      "Plan Rows": 1,
      "Plan Width": 41,
      "Actual Startup Time": 0.007,
      "Actual Total Time": 0.007,
      "Actual Rows": 1,
      "Actual Loops": 1,
      "Output": ["pk", "description", "flags"],
      "Shared Hit Blocks": 1,
      "Shared Read Blocks": 0,
      "Shared Dirtied Blocks": 0,
      "Shared Written Blocks": 0,
      "Local Hit Blocks": 0,
      "Local Read Blocks": 0,
      "Local Dirtied Blocks": 0,
      "Local Written Blocks": 0,
      "Temp Read Blocks": 0,
      "Temp Written Blocks": 0,
      "WAL Records": 0,
      "WAL FPI": 0,
      "WAL Bytes": 0,
      "Plans": [
        {
          "Node Type": "Seq Scan",
          "Parent Relationship": "Outer",
          "Parallel Aware": false,
          "Async Capable": false,
          "Relation Name": "hugedata",
          "Schema": "public",
          "Alias": "hugedata",
          "Startup Cost": 0.00,
          "Total Cost": 15406.01,
          "Plan Rows": 1000001,
          "Plan Width": 41,
          "Actual Startup Time": 0.006,
          "Actual Total Time": 0.006,
          "Actual Rows": 1,
          "Actual Loops": 1,
          "Output": ["pk", "description", "flags"],
          "Shared Hit Blocks": 1,
          "Shared Read Blocks": 0,
          "Shared Dirtied Blocks": 0,
          "Shared Written Blocks": 0,
          "Local Hit Blocks": 0,
          "Local Read Blocks": 0,
          "Local Dirtied Blocks": 0,
          "Local Written Blocks": 0,
          "Temp Read Blocks": 0,
          "Temp Written Blocks": 0,
          "WAL Records": 0,
          "WAL FPI": 0,
          "WAL Bytes": 0
        }
      ]
    },
    "Settings": {
    },
    "Planning": {
      "Shared Hit Blocks": 0,
      "Shared Read Blocks": 0,
      "Shared Dirtied Blocks": 0,
      "Shared Written Blocks": 0,
      "Local Hit Blocks": 0,
      "Local Read Blocks": 0,
      "Local Dirtied Blocks": 0,
      "Local Written Blocks": 0,
      "Temp Read Blocks": 0,
      "Temp Written Blocks": 0
    },
    "Planning Time": 0.035,
    "Triggers": [
    ],
    "Execution Time": 0.069
  }
]

Вопрос в том, как применяется ограничение в postgres?

  1. DB Engine выбирает 1000 (все) записей, затем передает их оператору ограничения, где он принимает первую запись и отбрасывает 999 записей.

ИЛИ

  1. DB Engine получает первую проверку записи обратно с помощью оператора ограничения, который принимает ее, затем DB Engines пытается выполнить поиск второй проверки записи с помощью оператора ограничения, который отклоняет ее, и DB Engine прекращает дальнейший поиск... Отличие от 1-го заключается в том, что DB Engine всегда работает (ищет/извлекает) для строк N+1 (ограниченное число), где в первой всегда получаются все строки в таблице.

Судя по моему поиску, оператор ограничения работает так, как было предложено в первом пункте, если это правда, то почему такая неэффективная реализация, или я что-то упускаю?

В документации по ограничениям говорится, что при создании плана запроса учитывается ограничение, но дает ли он результат в строке N+1 или «учтено» означает, что что-то еще не указано... https://www.postgresql.org/docs/ текущий/queries-limit.html

From my search... на самом деле вы не предоставляете никаких подробностей своего поиска, но он явно пытается сделать что-то вроде #2. Это не всегда возможно, конечно.
Richard Huxton 05.05.2024 10:19

«Мой поиск» — это план объяснения, в котором говорится, что дочерние узлы выполняются первыми, немногие люди, с которыми я разговаривал, говорят, что это всегда неэффективно по сравнению с использованием предложенияwhere между числовыми pk и ChatGPT.

Lau 05.05.2024 10:26

Беги explain analyze select * from hugedata limit 1

Adrian Klaver 05.05.2024 18:15

limit без order by — это своего рода случайный результат. Вряд ли вы этого хотите. Утверждения этих немногих людей, которых вы упомянули, не подтверждаются никакими планами запросов и поведением базы данных, и их мнение невозможно проверить.

Frank Heikens 05.05.2024 20:01

@FrankHeikens Адриан Клавер Мне действительно интересно узнать, что происходит на самом деле, независимо от мнения других людей, так что игнорируйте это… какой из них 1 или 2? и какие доказательства у нас есть, чтобы поддержать это?

Lau 05.05.2024 20:21

Пожалуйста, поделитесь своим планом запроса, используя explain(analyze, verbose, buffers, settings) для оператора SQL. В текстовом виде, пожалуйста, как обновление вашего вопроса.

Frank Heikens 05.05.2024 21:17

@FrankHeikens, обновил его со всеми параметрами. Глядя на план, кажется, что на этапе планирования все строки 1000001 назначаются для чтения запросом, но когда происходит выполнение, он считывает только 1 строку, то есть: фактическое количество строк является правильной интерпретацией. ?

Lau 06.05.2024 06:50

Как видите, он останавливается после 1 ряда. Выполнение занимает всего 0,069 миллисекунды.

Frank Heikens 06.05.2024 07:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Исполнитель PostgreSQL работает по требованию и сверху вниз.

Чтобы вычислить первую строку результата, она извлекает первую строку из узла Limit. Это, в свою очередь, извлекает первую строку из Seq Scan.

Когда PostgreSQL извлекает вторую строку результата из узла Limit, ему сообщается, что выполнение завершено.

в итоге при последовательном сканировании извлекается только одна строка.

Вы можете найти это в README исполнителя:

Исполнитель обрабатывает дерево «узлов плана». Дерево плана по существу конвейер по требованию операций обработки кортежей. Каждый узел, когда вызывается, создаст следующий кортеж в своей выходной последовательности или NULL, если нет доступно больше кортежей. Если узел не является примитивным сканированием отношений узел, у него будут дочерние узлы, которые он, в свою очередь, вызывает для получения входных данных. кортежи.

Любые ссылки на документы, подтверждающие это, кроме плана выполнения...

Lau 06.05.2024 09:36

Я добавил ссылку на исходную документацию.

Laurenz Albe 06.05.2024 10:11

Другие вопросы по теме