overextended / oxmysql

MySQL resource for FXServer.
https://overextended.dev/oxmysql
GNU Lesser General Public License v3.0
309 stars 192 forks source link

MySQL.update fsr stops code execution for a tick #222

Closed mcNuggets1 closed 4 months ago

mcNuggets1 commented 4 months ago

Issue checklist

Describe the bug I used prints before and after MySQL.update and it actually took a tick to execute. It halts the code for a full tick fsr. It shouldnt do that. Also I dont see it documented.

Screenshots If applicable, add screenshots to help explain your problem.

Code

    CreateThread(function()
        print(GetGameTimer())
        for i=1, 100 do
            MySQL.update("UPDATE owned_vehicles SET `stored` = 0 WHERE `owner` = @owner AND `plate` = @plate", {['@plate'] = "123", ['@owner'] = "123"})
        end

        print(GetGameTimer())
    end)

Expected behavior https://i.imgur.com/kzwwSQY.png

Additional context Add any other context about the problem here.

Server details

Database details

thelindat commented 4 months ago

GetGameTimer gets the game time in milliseconds. MySQL.update calls an export, and exports have a small amount of overhead.

You call the export 100 times, and it takes about 3ms; server ticks execute every 50ms.

darksaid98 commented 4 months ago

Based on your testing we're talking ~0,03ms of execution time for every invocation which is pretty damn good.

What you really should be doing in a real-world scenario like this though, is using MySQL.prepare, which will allow you to batch execute the query multiple times for a dataset.

MySQL.prepare("UPDATE `owned_vehicles` SET `stored` = 0 WHERE `owner` = ? AND `plate` = ?", 
    { -- Executes query once for each entry in this table
        { 
            'Owner1', 'SOMEPLATE'
        },
        {
            'Owner3', 'SOMEPLATE'
        },
        {
            'Owner98', 'SOMEPLATE'
        },
        {
            'Owner5', 'SOMEPLATE'
        }
    }
)   

Granted, that isn't equivalent to your code, since it only executes 4 queries. However, it does avoid the overhead of calling the export multiple times.

There's a good benchmarking example for oxmysql in the docs here: https://overextended.dev/oxmysql/benchmark#script which is more precise than using GetGameTimer.