Als erstes sollte man prüfen, ob die Datenbankverbindung während des gesamten Seitenaufbaus die gleiche ist. Ein ständiges Auf und Zumachen des Links vor und nach JEDER Query ist äußerst kontraproduktiv, da diese Operation an der Query am längsten dauert. Um das zu verhindern musst du die Connection offen halten, bis die Klasse zerstört wird (== Seitenaufbau finished)
Selbstverständlich
Ich hoffe Du programmierst objektorientiert.
Klar, habe auch zu den Zwecken eine auf MySQLi-basierende eigene DB-Class erstellt, die über weitere Sonderfunktionen verfügt.
Dann ist es einfach. Connection öffnen im Konstruktor und schließen im Destruktor. Die Connection Klasse unbedingt zur funktionierenden Singleton Klasse machen (sonst erstellt jede aufrufende Klasse seine eigene Connection...) und das wars auch schon.
Manchmal ist es aus Gründen der Performance aber auch wichtig, eine separate Connection zu erzeugen. Gerade bei größeren INSERT-Statements, bei denen man mit LAST_INSERT_ID() den Wert aus einem vorherigen Statement abgreifen möchte. Als Beispiel seien hier via AJAX aufgerufene (daher asnychrone) DB-Operationen zu nennen. Wenn hier keine separate Connection in Verbindung mit LAST_INSERT_ID() erzeugt wird, gute Nacht

.
Aber zu Singleton habe ich auch schon interessante Diskussionen geführt, die teilweise ohne Ergebnis blieben.
Singleton ist böse.
Es gibt in der PHP Welt nur 3 wichtige Gründe für den Einsatz eines Singleton:
1. Faulheit, grenzenlose Faulheit
2. Verhindern, dass man den Code ordentlich testen kann
3. Man möchte sich bei seinen Mitstreitern blamieren
Falls du dich beteiligen möchtest, gerne eine PN an mich
Das sollte bei 109 Requests (= Queries?) schon einiges bringen.
Das Tools versteht hier unter einem Request einen GET-Request (HTTP). Kein DB-Query.
Als nächstes kannst du anfangen Indizes in der DB zu erzeugen.
Wie gesagt, die DB umfasst mehrere GB und ist an sich optimiert
Das Bottleneck sind hier die GET-Requests an externe Dienste wie FB oder eben Google (Maps, AdSense).