Ответ 1
Вы не узнаете реальное состояние соединения, не пройдя провод, а SELECT 1
- достаточно хороший кандидат (возможно, вы можете придумать более короткую команду, которая занимает меньше времени разобрать, но по сравнению с задержкой в сети или даже обратной петлей эти сбережения будут незначительными.)
При этом я бы сказал, что пинговать соединение, прежде чем проверять его из пула, не лучший подход.
Вероятно, вам просто нужно, чтобы диспетчер пула соединений применял свою собственную политику keep-alive (timeout), чтобы не быть отключенным сервером (если не считать более серьезной проблемы с подключением, которая может повлиять на вас так или иначе, и менеджер вашего пула соединений не смог бы помочь в любом случае), а также , чтобы не запускать базу данных (думаю, дескрипторы файлов и использование памяти).
Поэтому сомнительно, на мой взгляд, какое значение тестирует условие подключения, прежде чем проверять соединение из пула. Возможно, стоит проверить статус подключения до того, как соединение будет проверено обратно в пул, но это можно сделать неявно, просто отметив соединение как грязное, когда возникает сложная ошибка SQL (или эквивалентное исключение) если только API, который вы используете, уже предоставляет вам вызов is-bad
.)
Поэтому я рекомендую:
- реализация политики поддержания работоспособности на стороне клиента
- не выполняет никаких проверок при проверке соединений из пула
- выполнение грязных проверок перед возвратом соединения в пул
- пусть код приложения относится к другим (не-таймаутам) исключительным условиям соединения
UPDATE
Из ваших комментариев будет видно, что вы действительно действительно хотите связать соединение (я предполагаю, что это связано с тем, что вы не имеете полного контроля или знания характеристик тайм-аута на сервере MySQL или промежуточного сетевого оборудования, такого как прокси-серверы и др.)
В этом случае вы можете использовать DO 1
в качестве альтернативы SELECT 1
; он немного быстрее - короче разобрать, и он не возвращает фактические данные (хотя вы получите TCP ack
s, поэтому вы все равно сделаете кругооборот, подтверждающий, что соединение все еще установлено.)
ОБНОВЛЕНИЕ 2
Что касается Joshua post, здесь трассировки захвата пакетов для различных сценариев:
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>
Как вы можете видеть, за исключением того факта, что пакет mysql_ping
равен 5 байтам вместо DO 1;
9 байтов, число обращений в оба конца (и, следовательно, задержка по сети) является точно таким же. Единственная дополнительная стоимость, которую вы платите с DO 1
, а не mysql_ping
, - это разбор DO 1
, который тривиален.