Каждое подключение к СУБД - это открытый сокет (TCP, IPC, или UNIX-сокет), плюс на обеих сторонах (клиент и сервер) структуры данных, в которых хранится состояние этого соединения, и (самое главное) кеши данных, которые могут вырастать до довольно больших размеров (например, если там застряли результаты всех выборок данных, выполненных через это соединение, такой вариант возможен). Но это не самое страшное. Гораздо хуже то, что в конфигах почти любой СУБД обозначен лимит активных подключений, после достижения которого сервер перестает принимать новые подключения. И этот лимит задан с расчетом на то, чтобы сервер справлялся с соответствующим количеством реально активных (то есть относительно нагруженных) подключений, не зависал при этом и не вычерпывал бы всю память при попытке выполнить запросы от всех подключений одновременно. Соответственно этот лимит задан довольно низко и не рассчитан на то, чтобы зависшие подключения накапливались десятками тысяч.
Но есть и приятная новость: короткоживущим процессам (типа скриптов на веб-сервере), можно не заботится о закрытии соединений вообще, потому что при уничтожении процесса в любом случае закрываются все открытые дескрипторы в том числе и сокеты, а при разрыве одной стороны сокета, автоматически закрывается и другая, все функции висящие в ожидании на этом сокете, вылетают с ошибкой, сервер безусловно рассчитан на это, он сразу освобождает все выделенные ресурсы, относящиеся к соединению, сокет которого оказался разорван.
Следует иметь в виду, что в зависимости от реализации веб-сервера сам процесс может и не уничтожаться по завершению работы скрипта.