sql >> Database >  >> RDS >> Mysql

voorbereidingsverklaring van golang sql-stuurprogramma

De verschillen kunnen subtiel, soms belangrijk en soms feitelijk niet bestaan.

In het algemeen wordt een voorbereid statement 1. voorbereid met de server (SQL geparseerd, uitvoeringsplan gegenereerd, enz.), 2. wordt uitgevoerd met de aanvullende parameters, en dan 3. wordt gesloten. Het stelt u in staat dezelfde SQL opnieuw te gebruiken met telkens andere parameters die worden doorgegeven, het kan helpen beschermen tegen SQL-injectie, het kan enkele prestatieverbeteringen bieden (stuurprogramma/protocol-specifiek, YMMV) en het voorkomen van herhaalde stappen, zoals bij het genereren van uitvoeringsplannen en het parseren van SQL in de voorbereiden stap hierboven.

Voor iemand die broncode schrijft, kan een voorbereide verklaring handiger zijn dan het aaneenschakelen van strings en deze naar de DB-server te sturen.

De DB.Query() methode neemt SQL als een string, en nul of meer argumenten (net als Exec() , of QueryRow() ). Een SQL-tekenreeks zonder extra argumenten zal precies opvragen wat u hebt geschreven. Echter, mits een SQL-string met tijdelijke aanduidingen en aanvullende argumenten, wordt er onder de motorkap een voorbereide instructie voor u gedaan.

De DB.Prepare() methode voert expliciet een voorbereide instructie uit, waaraan u vervolgens argumenten doorgeeft, zoals in:stmt.Exec(...args) .

Er zijn een paar dingen die de moeite waard zijn om over na te denken, in termen van de verschillen tussen de twee en waarom het een of het ander moet worden gebruikt.

U kunt DB.Query() . gebruiken zonder argumenten. Dit kan erg efficiënt zijn omdat het de prepare --> execute --> close . kan omzeilen volgorde die de voorbereide verklaring noodzakelijkerwijs doorloopt.

Je kunt het ook gebruiken met extra argumenten en tijdelijke aanduidingen in de queryreeks, en het zal een voorbereide instructie uitvoeren onder de dekens, zoals ik hierboven al zei. Het potentiële probleem hier is dat wanneer u een aantal vragen stelt, elk resulteert in een onder de motorkap voorbereide verklaring. Aangezien er extra stappen bij betrokken zijn, kan dit nogal inefficiënt zijn, aangezien het elke keer dat u die query uitvoert, opnieuw wordt voorbereid, uitgevoerd en afgesloten.

Met een expliciet voorbereide instructie kunt u die inefficiëntie mogelijk vermijden, aangezien u probeert de SQL die u eerder hebt voorbereid, opnieuw te gebruiken met mogelijk andere argumenten.

Maar dat gaat niet altijd zoals je zou verwachten... Door de onderliggende connectie pool die beheerd wordt door db/sql, is je "database connectie" behoorlijk virtueel. De DB.Prepare() methode zal de instructie voorbereiden tegen een bepaalde verbinding en vervolgens proberen diezelfde verbinding terug te krijgen wanneer het tijd is om uit te voeren, maar als die verbinding niet beschikbaar is, zal het er gewoon een pakken die beschikbaar is en zich opnieuw voorbereiden en uitvoeren tegen die verbinding. Als je dezelfde voorbereide verklaring steeds opnieuw gebruikt, zou je, onbewust, deze ook steeds opnieuw kunnen voorbereiden. Dit komt natuurlijk vooral aan het licht als je te maken hebt met veel verkeer.

Het is dus duidelijk wat u voor welke omstandigheid gebruikt, hangt af van uw specifieke gebruiksgeval, maar ik hoop dat de bovenstaande details u voldoende verduidelijken zodat u in elk geval de beste beslissing kunt nemen.

Bijwerken

Gezien de update in OP is er in wezen geen verschil wanneer de query maar één keer hoeft te worden uitgevoerd, aangezien query's met argumenten achter de schermen worden gedaan als voorbereide verklaringen.

Gebruik de directe methoden, b.v. DB.Query() en zijn analogen, vs. het expliciet gebruiken van voorbereide instructies, omdat dit zal resulteren in een wat eenvoudigere broncode.

Aangezien voorbereide instructies in dit geval worden gebruikt om veiligheidsredenen, kan het de moeite waard zijn om de beveiligingsproblemen op een andere manier aan te pakken en in plaats daarvan platte-tekstquery's te gebruiken, omdat dit de prestaties zal verbeteren. Eventuele winsten kunnen echter irrelevant zijn, tenzij er voldoende verkeer is (of als het verkeer naar verwachting in de toekomst aanzienlijk zal groeien) om de belasting van de server te verlichten. Nogmaals, het komt neer op het gebruik in de echte wereld.

Voor iedereen die geïnteresseerd is in enkele statistieken over het verschil tussen voorbereide verklaringen en directe zoekopdrachten in platte tekst, is er een goed artikel hier (die ook uitstekend werk levert door veel van het bovenstaande uit te leggen).



  1. De verbinding tussen client en server configureren Oracle 10g

  2. Hoe u het verschil tussen twee datums kunt afronden naar uren

  3. Kan het aantal rijen niet ophalen en ophalen bij gebruik van een door MySQLi voorbereide instructie

  4. #1025 - Fout bij hernoemen (errno:150) in mysql