1

I have a database class that I developed. But I have doubts about performance in case of load. There are two issues that I was curious about and couldn't find the answer even though I searched.

When the database connection is bound to a static variable in the class,

class DB
{
    static $connect;
    ......
    function __construct() 
    {      
        try {
             self::$connect = new PDO("{$this->db_database}:host={$this->db_host};dbname={$this->db_name};charset=utf8mb4", "{$this->db_username}", "{$this->db_password}");
             self::$connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
             self::$connect->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8mb4");
        } catch ( PDOException $e ){
             echo  '<b>ERROR: </b>'.$e->getMessage();
             exit;
        }
    }
}

PDO::ATTR_PERSISTENT => true

Does it have an equivalent ability?

Also, I didn't fully understand the pdo permalink logic, it uses the existing connection instead of opening a separate connection for each user. But how does he use the existing link here? For example "ip address" etc.

Thank you for your help.

Riga
  • 34
  • 5
  • that's completely **different** matters, absolutely unrelated to each other. – Your Common Sense Mar 20 '22 at 16:32
  • @YourCommonSense Are you saying that the given answer is wrong? So a mysql connection in a static variable does not provide a permanent connection? – Riga Mar 20 '22 at 16:36
  • **of course** it doesn't – Your Common Sense Mar 21 '22 at 03:37
  • It seems that you don't understand what a permanent connection is. And how PHP is executed in general. The permanent connection is a connection shared between different PHP executions. And a static variable is only static within the same PHP execution. It seems that your problem is only related to the same script execution and you shouldn't touch the permanent connection with a long pole. – Your Common Sense Mar 21 '22 at 07:03
  • Also, what is more important, you **ought** to ask about the **initial problem** you have - that with alleged 280 connections or something. NOT about some vague ideas you have on how to fix that problem. You are spoiling every answer with your comments that are unrelated to the question you asked – Your Common Sense Mar 21 '22 at 07:04

1 Answers1

0

Let me approach the issues from a different direction.

A program should have only one connection to the database. (There are rare exceptions.) Your code, as it stands, seems to be inconsistent. It has a single ("static") connection, yet the class can be instantiated multiple times, thereby connecting multiple times. (I don't want to depend on anything "persist" to clean up the inconsistency.)

Either make the class a singleton or otherwise avoid being able to call __construct a second time. One approach goes something like this:

class DB {
    private static $connect;
    ......
    public function __construct() {      
        if (! self::$connect) {
             self::$connect = ...
        }
    }
    public function Fetch(...) {
        self::$connect->...
        return ...;
    }

$con = new DB();
$data = $con->Fetch(...);

(plus suitable try/catch)

Note that that allows you to sub-class as needed.

Another approach might involve preventing the use of new:

    private function __construct() { ... }

plus having some public method invoke that constructor.

Here's another approach. It can be used on an existing class that you don't want to (or can't) modify:

function GetConnection() {
    static $db;
    if (! $db) {
        $db = new ...;
    }
    return $db;
}

$db = GetConnection();
$db->Fetch(...)'

As for "connection pooling", it is of limited use with MySQL. (Other products need it much more than MySQL does.) In my opinion, don't worry about such.

Do not use "auto-reconnect". If the connection dies in the middle of a transaction and is automatically restarted, then the first part of the transaction will be rolled back while the rest might get committed. That is likely to lead to data inconsistency.

Singletons, statics, globals, void*, critical sections all make me cringe. When I need such, I rush to find a way to "hide" it, even if that means writing cryptic code in some class(es).

For performance, MySQL really needs a single connection throughout the program. I compromise by hiding the connection in a "static" that serves at a "global". Then I hide that inside the class that I use to abstract the object(s).

I agree with Karwin's [now delete] Answer -- that this discussion is "much ado about nothing". MySQL performance is mostly about indexing, query formulation, and even the architecture of the application. Not about connections, common code elimination, redundant function calls, etc.

Rick James
  • 135,179
  • 13
  • 127
  • 222
  • The reason I use a static value in this class is because I don't want to use globals in different functions. Because it confuses global affairs. There are methods such as select, where, insert, update in the class. You can consider the Crud system. As you said, function example() { $db = new DB(); } Will this open a new link ? I was using this usage as it confused global stuff as I mentioned. – Riga Mar 20 '22 at 18:59
  • @Riga - I added some more paragraphs. – Rick James Mar 20 '22 at 19:06
  • @Riga - Where we differ... My code prevents connecting a second time. The test on the static is a lot cheaper than going through the connection code a second time. – Rick James Mar 20 '22 at 19:10
  • Are you saying that my code will reconnect when the class is rebuilt? Then what is the meaning of static variable :), I may have misunderstood. – Riga Mar 20 '22 at 19:12
  • @Riga - As I read your code, a second "new DB()" will disconnect the existing connection and start over in connecting. [I do not know how much, if any, of that is skipped due to PERSIST.] Instead, I prefer to demand that the user think of there being only one connection for the lifetime of the web page (or program). – Rick James Mar 20 '22 at 19:21
  • @Riga - "16 online users" is trivial. If there are a thousand "connected" and "dozens" running queries at an instant, then we can talk about performance of the queries -- connections is not the issue. – Rick James Mar 20 '22 at 19:22
  • `SHOW GLOBAL STATUS LIKE 'Thread_running';` and `SHOW FULL PROCESSLIST;` but ignore any in "Sleep" state. Do you see 16-18 "running"? What queries are they running? Can those queries be improved? (Show us the queries, together with the "Time" column.) – Rick James Mar 20 '22 at 19:26
  • It is quite normal for lots of people to be logged in -- maybe even 280. But probably only a few are actively running any query. The rest are typing on the keyboard or reading the screen. Even the metric of "queries per second" can reach into the hundreds without the server breaking a sweat. (Of course, it is possible to write heavy queries that would be a problem.) – Rick James Mar 20 '22 at 19:30
  • 280 _separate_ users that are _currently_ connected _cannot_ share a connection. If one of them disconnects, the 'next' user may be able to grab that connection (based on exactly how 'persist' works). – Rick James Mar 20 '22 at 19:32
  • Back to your last question... When an object is built from a class, the `__construct()` is always run. The code you have says, unconditionally, `self::$connect = ...`. That is interpreted as (1) destroy anything that is in `$connect` and (2) reassign to it `...`. Maybe somewhere in the bowels of `...`, there is a conditional shortcut because of "persist". But still some code will be performed. – Rick James Mar 20 '22 at 19:39