[Python] Opzet api endpoint met meerdere database calls

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Crack_david
  • Registratie: September 2007
  • Laatst online: 19-09 20:36
Ik ben een api aan het ontwikkelen die een endpoint heeft van waaruit +/- 20 losse database calls gegenereerd worden. De queries varieren in looptijd, van 100ms tot 2 seconden.

Mijn opzet:

- FastAPI api
- MS SQL database

Wanneer een request binnen komt op de API wordt er 1 functie aangeroepen, die functie roept vervolgens verschillende losse functies aangesproken die afzonderlijk van elkaar een database connectie maken en daar de beschikbare data ophalen.

Mijn eerste gedachte was dat dit het beste Asynchroon kan zodat de queries niet op elkaar wachten en heb hiervoor AIOODBC geprobeerd, door een connectie pool op te zetten en deze via een fastapi Dependency mee te geven aan de eerste functie, en binnen die functie connecties te maken en die mee te geven aan de losse queries.

Mijn responsetijd ging (lokaal) van 3 naar 4 secondes, dus dat was niet heel succesvol :-)

Ik ben nu aan het zoeken naar een betere manier om dit op te zetten maar ik raak het overzicht tussen de verschillende termen een beetje kwijt. Is asynchroon wel de beste manier, of kan dit beter via multi-threading, of is het beter om dit gewoon door de DB driver zelf op te laten lossen?

Alle reacties


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 22:27
Crack_david schreef op vrijdag 10 december 2021 @ 10:42:
Ik ben een api aan het ontwikkelen die een endpoint heeft van waaruit +/- 20 losse database calls gegenereerd worden. De queries varieren in looptijd, van 100ms tot 2 seconden.

Mijn opzet:

- FastAPI api
- MS SQL database

Wanneer een request binnen komt op de API wordt er 1 functie aangeroepen, die functie roept vervolgens verschillende losse functies aangesproken die afzonderlijk van elkaar een database connectie maken en daar de beschikbare data ophalen.

Mijn eerste gedachte was dat dit het beste Asynchroon kan zodat de queries niet op elkaar wachten en heb hiervoor AIOODBC geprobeerd, door een connectie pool op te zetten en deze via een fastapi Dependency mee te geven aan de eerste functie, en binnen die functie connecties te maken en die mee te geven aan de losse queries.

Mijn responsetijd ging (lokaal) van 3 naar 4 secondes, dus dat was niet heel succesvol :-)

Ik ben nu aan het zoeken naar een betere manier om dit op te zetten maar ik raak het overzicht tussen de verschillende termen een beetje kwijt. Is asynchroon wel de beste manier, of kan dit beter via multi-threading, of is het beter om dit gewoon door de DB driver zelf op te laten lossen?
Zijn de 20 losse databasecalls nodig? Of kan je ze samenvoegen (b.v. in een stored procedure)?
Daarnaast kan je nog kijken of er wat te optimaliseren valt d.m.v. indexes op je tabellen - kans is groot dat dit ook een flinke prestatiewinst oplevert.

Acties:
  • +1 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:11

Creepy

Tactical Espionage Splatterer

Ik denk dat je eerst eens moet gaan zoeken wat nu de vertraging veroorzaakt. Ik weet niet of je meer dan 1 database benadert, maar zo ja, dan lijkt het me ook logisch dat je 1 connectie maakt en daar al je queries op afvuurt. En of je queries parallel kan uitvoeren is afhankelijk van de queries en op welke tabellen ze allemaal impact hebben. Met puur en alleen select queries zou ik zeggen dat je ze parallel moet kunnen uitvoeren maar of het echt winst gaat opleveren gaat weer afhankelijk zijn van de query en tabellen (wordt er een index gebruikt, past de tabel of de index volledig in het geheugen etc. etc.)

Maar een wilde gok: met 3 tot 4 seconden voor een paar queries ben je hele grote tabellen aan het benaderen (lees: een tabel van 10-tallen of 100+GB) of gebruik je niet de juiste indexen, of allebei. En dan zit het hem dus niet in je connectie pool of al dan niet parallel queries uitvoeren.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Crack_david
  • Registratie: September 2007
  • Laatst online: 19-09 20:36
Ik heb de queries afzonderlijk op gezet zodat ik ze een voor een kan monitoren en optimaliseren. Het gaat om het ophalen van feature informatie voor het uitscoren van een ML model.
De data komt uit een database server, maar wel met verschillende databases daarin, en er worden ook joins gedaan op tabellen uit verschillende databases. Mijn connectie string is dus op server niveau en iedere query heeft [db_naam].[tabel_naam].[kolom_naam].
Er zitten inderdaad een aantal erg grote tabellen bij waar gebruik van gemaakt wordt waar ik zelf qua beheer niet aan kan doen. Daarom wil ik er in ieder geval voor zorgen dat de response tijd puur afhankelijk is van de langs lopende query en niet dat de andere queries moeten wachten op deze.

Acties:
  • +1 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 20:07
Ik denk dat multithreading de beste oplossing hiervoor is.

Dan maak je maximaal van de standaard Python functionaliteit gebruikt met de beste optimalisatie voor je gebruikte platform.
Python multithreading is namelijk tamelijk efficiënt.

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.