Комментарии 12
Все хорошо, но в исследовании как-то учитывались индексы на таблицах? Ведь, токсичные запросы могут возникать когда нехватает или плохо построены индексы.
Спасибо за интерес к теме!
Мы в первую очередь решали задачу отслеживать токсичные запросы. Запрос может выполнятся долго, просто потому что данных очень много и в запросе участвует много таблиц итд. и индекс не всегда поможет(или его не рационально делать тк запросов мало). Но идея про автотюнинг БД интересная, но это уже про следующий шаг - рекомендации по настройке(на основании нагрузки использования). И такие решения есть, например, я иногда поглядывал на проект от Andy Pavlo, Ottertune(к сожалению, больше не развивается, но есть много других решений ).
Если запрос выполняется долго из-за того, что много данных - это проблема прежде всего индекса т.к. это означает, что в выборку по индексу попадает много данных, которые потом нужно еще группировать и фильтровать, а значит cardinality индекса очень низкий.
Если же вам нужно подключать много таблиц к запросу, то, вроде очевидно, что надо следить за планом запроса и использовать для JOIN поля с ключами и индексами. JOIN вообще самая медленная операция в РСУБД. Альтернативным путем иногда является переход на SELECT-driven модель, чтоб избежать JOIN'ов.
Но в любом случае получается, что задача сводится к анализу статистики запрсов и вытягиванию самых медленных. Затем их рефакторинг и получаем то, что надо.
Убедили) я не готов углубляться в администрирование posgresql, я могу легко уступить. В данной задаче более интересна составляющая ML.
Если абстрагироваться от psql и подумать о MPP системах, где данных легко могут быть сотни TB и не везде оптимизации экономически выгодны. Плюс логика может быть разной, например, запрос запущенный другой системой и работающий 1 час - это может быть нормально, а вот если это запрос от пользователя, то это уже может быть токсичный итд
На самом деле это касается не только pgsql. Я, например, часто статистику и аналитику тяну из кликхауса. И если на огромных таблицах не учитывать ключи и особенности работы самой СУБД, то можно получить запросы которые будут работать час. Конечно, в некоторых случаях их не избежать (типа bulk insert), но что касается того что отдается пользователю, то оно должно отдавать все же быстро и здесь разные критерии оценки. В этом смысле разделение на OLAP и OLTP дизайн для таблиц помогает.
На самом деле не только время, но для упрощения мы будем считать только время, так как это ключевой параметр.
Если бы авторы немного вникли в то, как выполняет запросы например Spark, то поняли бы, что время вообще не параметр само по себе, потому что его можно разменять на ресурсы. Т.е., вы можете выделить на выполнение запроса скажем, 10 ядер CPU, и 10 гигабайт памяти, а можете - 1000 ядер и 10 терабайт. И результаты по времени выполнения будут совершенно разные. Время актуально при условии, что ресурсы фиксированы, а это далеко не всегда так.
Ну и как резонно выше замечено, на выполнение запросов влияет множество факторов, и кроме наличия индексов можно еще назвать наличие актуальных статистик, про которое (в отличие от наличия индекса) мы вообще ничего не знаем.
Я, например, начал использовать Spark c версии 1.Х :)
Раскрою утверждение - если у нас есть запрос и зная что он выполняется на X ресурсах - Y минут мы можем предположить сколько он будет выполнятся на доступных ресурсах и нам такая задача показалось решаемой. (Если брать пример с Spark на YARN - то это будет измеряться в memorySeconds и vcoreSeconds. Зная время выполнения запроса Х и зная значения memorySeconds и vcoreSeconds предсказать время выполнения запроса Х с другими ресурсами можно довольно точно).
Мы же пробуем решить ML-задачу и у нас нет задачи углубляться в настройки БД, если там статистики, как распределены данные, есть ли там индексы итд - а хотим понять примерное время выполнение запроса (с учетом ресурсов и более корректно будет называть это cost). И по большому счету нам важна предсказуемость системы, а не знания о наличии индексов - и в случае добавления индексов или удаления большого объема данных итд - нам нужно будет дообучать/переобуччать модель.
ps Если углубляться в тему про ML - существуют "учебные" проекты даже по предсказанию оптимального плана запроса, например, https://dl.acm.org/doi/abs/10.1145/3588963
Я, например, начал использовать Spark c версии 1.Х :)
Я тоже :)
Зная время выполнения запроса Х и зная значения memorySeconds и vcoreSeconds предсказать время выполнения запроса Х с другими ресурсами можно довольно точно).
Вот тут я что-то не уверен. Ну т.е. наверное да, вы правы - что-то предсказать можно, если мы понимаем, что запрос как-то параллелится. Просто знание о "доступных ресурсах" - это фактически в реальности знание о том, что у нас с вами работает на кластере, в том числе помимо нашего запроса, и в общем-то в реальности мы довольно редко хотим оптимизировать один запрос ценой заваливания ресурсами - потому что остальные тогда что будут делать?
memorySeconds и vcoreSeconds.
Ну вот я к этому и клоню, что скорее это показатель эффективности, а не просто время.
Ну вот я к этому и клоню, что скорее это показатель эффективности, а не просто время.
Спасибо, что обратили на это внимание, действительно, в статье это часть задачи не освещена и сильно упрощена!
В постгресе можно подкрутить настройки памяти (work_mem), и вместо адского торможения на диске, запрос будет летать в памяти.
Спасибо за комментарий!
Конечно можно, вопрос целесообразности и экономической эффективности для конкретной задачи и объема данных. Для ML задачи это не должно оказывать эффекта, если этот параметр постоянно включен или выключен и история выполнения запросов с таким-же значением параметра. А если поразмыслить над задачей ускорения - можно еще задействовать GPU карточку и считать часть запросов с помощью либы RAPIDS на GPU. Или использовать специальные БД с поддержкой GPU Accelerated - например, тут есть сравнение https: //arxiv.org/html/2406.13831v1
Поиск «токсичных» SQL-запросов