New on LowEndTalk? Please Register and read our Community Rules.
All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.
All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.
Why is incrementing a variable slow in mysql/php?
hopefully someone can explain this, as I am at a loss:
$_DB = new MyPDO("mysql:host=127.0.0.1", DB_USER, DB_PASS); while($i++<1000000) { $_DB->exec("SET @insert_count = @insert_count + 1"); }
This takes about 15 seconds to complete on a single Intel core. CPU usage for this is high, but I have no idea why. ->query() takes twice as long, 35s.
If i do @insert_count = $i, it still takes as long.
So, why is SET so slow??
FWIW: PHP 8.3/MariaDB 11.5


Comments
Thanks ChatGPT
The slowness you're observing with SET in your code can be attributed to several factors that are intrinsic to how MySQL handles session variables and the overhead associated with the operations:
Key Points to Consider:
Solutions to Improve Performance:
Batch Updates:
Final Takeaway:
The slowness isn't because SET is inherently slow—it’s relatively efficient for what it does. However, executing it repeatedly in a loop introduces avoidable overhead that becomes significant at scale. Moving the logic to PHP or optimizing your interaction with MySQL should address the issue effectively.
but this is what im asking - why is it so slow?
incrementing (or even setting it to the same value as Ive found) mysql @var = 15s
incrementing in PHP: 5ms
afaik global variables dont cause writing to logs etc and im not seeing disk activity, just cpu.
And it really is slow, I have actual queries that update rows in a table, that run faster than this (prepared). i.e. insert/update 1m rows < 15s
Looks like its simply the php->mysql connection overhead. Damn, will see if i can improve that.
For php there is no connection overhead and php need less cpu to run these task as it keeps your data in strings (ram not in disk) but mysql needs more due to handling a lot of background things and keep loop data in disk. That's why php loop is faster than db. To optimize your DB connection you need to
1. use persistent connection
2. use local server and disk
3. High frequency cpu and nvme disk (good io)
4. and most importantly do not close db connection after each and every query. Close it only after finishing your all queries/tasks.
5. Also you can disable mysql name resolving and increase your inno db log and buffer size (for innodb storage engine). On our testing we found a great improvement after optimizing mysql config as per server specifications.You can use mysql tuner it's not perfect. but do the job.
Try the same with increment in a stored procedure?
If you want performance and have it saved somewhere just do it into a .txt file or something.
MySQL will perform worse for a multitude of reasons.
If you really want SQL and both SQL and the PHP are on the same machine, try SQLite3 but do check how to improve its performance with PRAGMAs like WAL file, etc.
Really want performance and don't care about losing your data? You can create the SQLite3 db in memory.
You can also increase the performance of PHP, if that counter is like a visitor counter that will trigger on a visit or page view and not just something that you run once from the command line, you can try setting up swoole or workerman which use a different execution model than the most popular PHP-FPM, that should improve the performance by a lot but you may need to change a few things in your application for it to work with it, for example no exit() or die()
Thanks guys,
in this case i just moved the counter to PHP, I just liked the idea of counting within my PDO class using a Mysql variable, but just surprised how it ended up using a noticeable amount of CPU time.
You may also try to scoop soup with fork. It somehow works, but not efficient. Congrats on finding the most performant solution.
AFAIK, in MySQL there LOCK flag when UPDATE data happen (it got worse when you use SET statement so it does double query check) so it would wait last UPDATE query to totally complete to process any next query.