Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use INSERT...ON DUPLICATE KEY UPDATE optimization #19

Open
ejunker opened this issue Jan 14, 2020 · 5 comments
Open

Use INSERT...ON DUPLICATE KEY UPDATE optimization #19

ejunker opened this issue Jan 14, 2020 · 5 comments

Comments

@ejunker
Copy link

ejunker commented Jan 14, 2020

Currently, the code uses RouteUsage::updateOrCreate() which first performs a SELECT query and then either an INSERT or UPDATE query. It is doing 2 queries for every request. If using MySQL then we can use INSERT...ON DUPLICATE KEY UPDATE query which will only need to do 1 query and since the identifier column has a UNIQUE index, it will automatically do an update if the identifier already exists.

I don't think Laravel supports those types of queries but you can use a library like:
https://github.com/yadakhov/insert-on-duplicate-key

The code might look something like this:

        $attrs = $this->extractAttributes($event);

        if (config('route-usage.on-duplicate-key-update')) {
            RouteUsage::insertOnDuplicateKey([$attrs]);

            return;
        }

        RouteUsage::updateOrCreate(...);

I assume that doing 1 query instead of 2 would be faster but some testing would need to be done to see if it is actually faster.

UPDATE: I just noticed in #4 that you used to use this type of query and then removed it to support other databases. If you make it a config option then people using MySQL can use the optimization and other databases will continue to use updateOrCreate()

@julienbourdeau
Copy link
Owner

I'd definitely love to improve it and have a better query for each database. I'm not sure yet what would be the best way.

I was thinking about a macro on the model which registers the correct SQL query depending on your database

@ingalless
Copy link
Contributor

@julienbourdeau I like this idea. I stumbled across a method available on the DB facade that might help with this too?

DB::getDriverName() // e.g. 'sqlsrv'

@ejunker
Copy link
Author

ejunker commented Feb 27, 2020

Actually, it should be possible to support multiple databases using this package:
https://github.com/staudenmeir/laravel-upsert

From the README

  • MySQL 5.1+: INSERT ON DUPLICATE KEY UPDATE
  • MariaDB 5.1+: INSERT ON DUPLICATE KEY UPDATE
  • PostgreSQL 9.5+: INSERT ON CONFLICT
  • SQLite 3.24.0+: INSERT ON CONFLICT
  • SQL Server 2008+: MERGE

@julienbourdeau
Copy link
Owner

i'll have a look 👍

@ejunker
Copy link
Author

ejunker commented Oct 13, 2020

As of Laravel 8.10 there is built-in support for upsert. laravel/framework#34698

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants