Je weet de echte staat van de verbinding niet zonder over de draad te gaan , en SELECT 1
is een goed genoeg kandidaat (u zou misschien een kortere opdracht kunnen bedenken die minder tijd kost om te ontleden, maar vergeleken met netwerk- of zelfs loopback-latentie zouden die besparingen onbeduidend zijn.)
Dit gezegd hebbende, zou ik zeggen dat een verbinding pingen voor het bekijken vanuit het zwembad is niet de beste aanpak .
U moet waarschijnlijk gewoon uw verbindingspoolmanager zijn eigen keep-alive (time-out) beleid laten afdwingen om te voorkomen dat de verbinding door de server wordt verbroken (afgezien van een ernstiger interveniërend verbindingsprobleem, dat u toch al midden in de reguliere operaties zou kunnen treffen - en waarmee uw verbindingspoolmanager sowieso niet zou kunnen helpen), evenals om de database niet te belasten (denk aan filehandles en geheugengebruik) onnodig.
Het is daarom naar mijn mening de vraag welke waarde het testen van connectiviteitscondities voordat een verbinding uit de pool wordt uitgecheckt, echt heeft. Het kan de moeite waard zijn om de verbindingsstatus te testen voordat een verbinding weer wordt ingecheckt in de pool , maar dat kan impliciet worden gedaan door eenvoudigweg de verbinding als vuil te markeren wanneer een SQL-harde fout (of gelijkwaardige uitzondering) optreedt (tenzij de API die u gebruikt al een is-bad
blootlegt -like oproep voor jou.)
Ik zou daarom aanraden:
- implementeren van een keep-alive-beleid aan de clientzijde
- geen controles uitvoeren bij het uitchecken van verbindingen uit de pool
- het uitvoeren van vuile controles voordat een verbinding wordt hersteld naar de pool
- laat de applicatiecode omgaan met andere (niet-time-out) uitzonderlijke verbindingsvoorwaarden
UPDATE
Uit je opmerkingen blijkt dat je echt echt de verbinding wilt pingen (ik neem aan dat dit komt omdat je geen volledige controle hebt over of kennis hebt van de time-outkenmerken op de MySQL-server of tussenliggende netwerkapparatuur zoals proxy's enz.)
In dit geval kunt u DO 1
gebruiken
als alternatief voor SELECT 1
; het is marginaal sneller -- korter om te ontleden, en het retourneert geen werkelijke gegevens (hoewel u zal verkrijg de TCP ack
s, dus u doet nog steeds de retourvlucht om te bevestigen dat de verbinding nog steeds tot stand is gebracht.)
UPDATE 2
Over Joshua's bericht , hier zijn traceergegevens voor pakketopname voor verschillende scenario's:
SELECT 1;
13:51:01.463112 IP client.45893 > server.mysql: P 2270604498:2270604511(13) ack 2531191393 win 1460 <nop,nop,timestamp 2983462950 59680547>
13:51:01.463682 IP server.mysql > client.45893: P 1:57(56) ack 13 win 65306 <nop,nop,timestamp 59680938 2983462950>
13:51:01.463698 IP client.45893 > server.mysql: . ack 57 win 1460 <nop,nop,timestamp 2983462951 59680938>
DO 1;
13:51:27.415520 IP client.45893 > server.mysql: P 13:22(9) ack 57 win 1460 <nop,nop,timestamp 2983488906 59680938>
13:51:27.415931 IP server.mysql > client.45893: P 57:68(11) ack 22 win 65297 <nop,nop,timestamp 59681197 2983488906>
13:51:27.415948 IP client.45893 > server.mysql: . ack 68 win 1460 <nop,nop,timestamp 2983488907 59681197>
mysql_ping
14:54:05.545860 IP client.46156 > server.mysql: P 69:74(5) ack 78 win 1460 <nop,nop,timestamp 2987247459 59718745>
14:54:05.546076 IP server.mysql > client.46156: P 78:89(11) ack 74 win 65462 <nop,nop,timestamp 59718776 2987247459>
14:54:05.546092 IP client.46156 > server.mysql: . ack 89 win 1460 <nop,nop,timestamp 2987247459 59718776>
Zoals je kunt zien, behalve het feit dat de mysql_ping
pakket is 5 bytes in plaats van DO 1;
's 9 bytes, is het aantal roundtrips (en bijgevolg de netwerk-geïnduceerde latentie) precies hetzelfde. De enige extra kosten die u betaalt met DO 1
in tegenstelling tot mysql_ping
is het ontleden van DO 1
, wat triviaal is.