169 похожих чатов

Всем привет! Кто нибудь знает почему в graphql есть изначально

эта проблема с n+1 запросов. И одно из решение этой проблемы было реализовано в рамках не самой технологии, а отдельной библиотекой, что скорей всего говорит о том, что для них это не проблема?

2 ответов

10 просмотров

Потому что запросы к базе изначально атомарные

Хорошо поставленный вопрос и содержит уже сам в себе ответ. В реализации самой спецификации GraphQL нет проблемы N+1. Графкуэль берет и выполняет запрос который прислал клиент. Проблема N+1 возникает непосредственно в вашем коде резолверов. В коде который вы написали сами. Если чутка “умнее” написать свой код, например с помощью DataLoader’а, то проблема решается. Описание проблемы N+1: эта проблема возникает, когда вы запрашиваете Список элементов и к каждому элементу этого списка запрашиваете связные ресурсы. В графкуэль-запросе попросили 100 статей, и к каждой статье запросили данные автора. Чтобы выполнить такой запрос клиента, необходимо (вариант ИЗИ): - получить 100 статей из базы (1 запрос в БД) - из каждой статьи взять id автора - сделать отдельный запрос на получение данных автора по полученному id шагом выше (N запросов в БД) Как такая проблема решается с DataLoader’ом (вариант НОРМ) - получить 100 статей из базы (1 запрос в БД) - из каждой статьи взять id автора - положили id автора в DataLoader, который возвращает promise (N операций отложи ID) - на следующий тик eventLoop’а выполнить один запрос findMany (вместо findById) по всем собранным id-шникам авторов (1 запрос в БД) - полученных авторов отдать в DataLoader в правильном порядке, которые разрезолвит промисы на 3-ем шаге. Как решается проблема по другому без DataLoader (вариант ХАРД) - Вы получили запрос от клиента, и можете в резолвере на первом (верхнем) уровне получить из 4-го аргумента info AST-дерово запроса. Согласно этого AST’a сразу сделать большой запрос с JOIN’ами в базу, и полченные данные трансформировать в форму которую запросил клиент. Т.е. у вас резолверы только на верхнем уровне. По такому пути, Hasura работает. —— Как же мы незаметно попадаем на проблему N+1? - 1) Решили описать тип Post - 2) Потом описали тип Author - 3) Описываем связь 1 к 1 - добавляем поле Post.author и в нем просто по authorId дергаем запись автора из базы через findById. …некоторое время спустя… - 4) А давай-ка прикртим в Query.postMany поле, которое будет возвращать список Post. …бац, и у вас незаметно появилась проблема N+1… На шаге 4 вы ничего страшного не сделали, просто запросили список статей. Корень проблемы в шаге 3 - когда вы его реализовывали, вы даже и не думали что создавая такую простую связь по id через findById, она может быть использована как то “неоптимально”. А именно – будет запрошана кучу раз в одном запросе от клиента. Итог прост: если вы “связываете” между собой два типа (Post и Author), то старайтесь сделать резолвер подготовленным к множественному вызову в рамках одного запроса. например как написано здесь: https://github.com/nodkz/conf-talks/tree/master/articles/graphql/dataloader —— Ах, да. Проблема N+1 также существует и с REST API, просто она менее очевидна, но смысл тот же. В тупую дернули список статей, а потом дергаем описание авторов по одному (нагрузка на бэк такая же как и с GraphQL). Как решаете эту проблему с REST API: - новая агрегационная ручка (похоже на вариант ХАРД выше) - на клиенте собираем список авторов в какой-нить масивчик, а потом через метод findMany дергаем всех за один запрос (похоже на вариант НОРМ выше) - нифига не делаем, бэкендеры там все кэшируют (похоже на вариант ИЗИ выше)

Похожие вопросы

Обсуждают сегодня

Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
лучше скажите, причём тут паскаль?
Alexey Kulakov
36
Чтобы перехватить все нажимания буков на форме, надо хук ставить? Пробовал на форме ОнКейДаун, оно ловит клаву если фокус не на компоненте с вводом текста
Serjone
15
Народ! Впервые клиенту пришло письмо от РКН, у вас, дескать, есть яндекс метрика, а нигде не написано, что вы ее юзаете. Никто не сталкивался?
Sasha Beep
14
Всем привет! вывожу на общей стр дочерние ресурсыв каждом ресурсе галерея, и первая фотка должна выводиться на общей [!DocLister? &prepare=photo !]
Alekso
12
А можно вопрос? Мне сегодня сказали что у меня функция (которая просто заполняет массив значениями) не правильная void Full(double * arr, int n) { for (int i = 0; i < n; i...
† C E †
7
День добрый, подскажите пожалуйста, есть ли какой-то способ сказать ребару не компилировать определённое приложение? Всю доку их перечиатл ничего подобного не нашёл
Кирилл
14
Добрый вечер. Хочу чтобы у меня в классе поле было функцией, которая возвращает строку. Делаю так: interface ... TGetOutPath = function : String of object; ... protec...
Kirill Filippenok
12
Здравствуйте, хочу сделать HelloWorld в консоли Дельфи, но функция API ничего не выводит, что я делаю не так? program Hello; {$APPTYPE CONSOLE} uses System.SysUtils, WinAPI.Wi...
Sergey Vinogradov
20
Это может быть все-таки не флудвейт? у меня ботфазер принимает изменения и отображает даже что они изменились, на видео видно что он прислал якобы уже измененное описание, н...
OVERLINK
13
Карта сайта