Nie poznasz prawdziwego stanu połączenia bez przejścia przez przewód i SELECT 1
jest wystarczająco dobrym kandydatem (prawdopodobnie można by wymyślić krótsze polecenie, którego parsowanie zajmuje mniej czasu, ale w porównaniu z opóźnieniem sieci lub nawet pętli zwrotnej te oszczędności byłyby nieznaczne).
Biorąc to pod uwagę, twierdzę, że pingowanie połączenia przed sprawdzanie tego z puli nie jest najlepszym podejściem .
Prawdopodobnie powinieneś po prostu poprosić swojego menedżera puli połączeń wymusić własną politykę utrzymywania aktywności (przekroczenia limitu czasu) aby uniknąć rozłączenia przez serwer (bez poważniejszego problemu z połączeniem, który i tak mógłby wpłynąć na ciebie w trakcie zwykłych operacji – i w którym menedżer puli połączeń i tak nie byłby w stanie pomóc), a także aby nie obciążać bazy danych (pomyśl o uchwytach plików i wykorzystaniu pamięci) niepotrzebnie.
Moim zdaniem jest więc wątpliwe, jaką wartość ma testowanie stanu łączności przed sprawdzeniem połączenia z puli. Warto przetestować stan połączenia zanim połączenie zostanie ponownie sprawdzone w puli , ale można to zrobić niejawnie, po prostu oznaczając połączenie jako brudne, gdy wystąpi twardy błąd SQL (lub równoważny wyjątek) (chyba że używany interfejs API już ujawnia is-bad
- jak zadzwoń do ciebie.)
Dlatego polecam:
- wdrażanie polityki utrzymywania aktywności po stronie klienta
- niewykonywanie żadnych kontroli podczas sprawdzania połączeń z puli
- wykonywanie brudnych kontroli przed zwróceniem połączenia do puli
- niech kod aplikacji poradzi sobie z innymi (bez limitu czasu) wyjątkowymi warunkami połączenia
AKTUALIZACJA
Z Twoich komentarzy wynikałoby, że naprawdę naprawdę chcesz pingować połączenie (zakładam, że dzieje się tak dlatego, że nie masz pełnej kontroli ani wiedzy o parametrach limitu czasu na serwerze MySQL lub sprzęcie sieciowym, takim jak serwery proxy itp.)
W takim przypadku możesz użyć DO 1
jako alternatywa dla SELECT 1
; jest marginalnie szybsze — krótsze do przeanalizowania i nie zwraca rzeczywistych danych (chociaż będziesz pobierz ack
TCP s, więc nadal wykonasz podróż w obie strony, sprawdzając, czy połączenie jest nadal nawiązane).
AKTUALIZACJA 2
Odnośnie postu Joshuy , oto ślady przechwytywania pakietów dla różnych scenariuszy:
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>
Jak widać, z wyjątkiem faktu, że mysql_ping
pakiet ma 5 bajtów zamiast DO 1;
9 bajtów, liczba podróży w obie strony (i w konsekwencji opóźnienia wywołane przez sieć) jest dokładnie taka sama. Jedyny dodatkowy koszt, który płacisz za pomocą DO 1
w przeciwieństwie do mysql_ping
jest parsowanie DO 1
, co jest trywialne.