alexanderhempel's avatar

Count collection records slower than insert

Hello,

I am using Laravel 5 and have a running mulitple file upload implementation via Dropzone. Now, i like to store a position number for a new file:

        $count = SplashImage::count();
        $this->position = !$count ? 0 : $count;

This gives me the correct position, when i upload a single file.
But when i upload multiple files i get something like this:

  • file 1: 0
  • file 2: 0
  • file 3: 2
  • file 4: 2
  • ect.

It seems the count query is slower then the forthcoming request.

Has someone an idea how to fix this?

0 likes
13 replies
thomaskim's avatar

Why don't you just use the auto-incrementing ID?

alexanderhempel's avatar

I need to update the position value but the auto-increment ID is immutable.
At the end of the day, I want a sortable list of records, ordered by position.

One idea is to let php sleep for 500ms after upload.
But this feels really awful.

ohffs's avatar

@alexanderhempel what's the problem with the ID being immutable? The way you are doing it just now will very likely always give you bad results.

phildawson's avatar

get the max position and then on the inserts include the incremented position attribute.

phildawson's avatar

You don't want to be updating the auto-incrementing primary key

you want to be doing two queries getting the id and using that in the next like doing

INSERT INTO table(position) SELECT MAX(position)+1 FROM table;
thomaskim's avatar
Level 41

@alexanderhempel For your Dropzone settings, you can set it so that it does not try to upload everything at once and does it sequentially.

Dropzone.options.myAwesomeDropzone = {
    // This uploads 1 at a time and so it waits till 
    // the previous one is done before 
    // starting the next upload
    parallelUploads: 1
};

This should make it so that your count() method works now.

There's also probably a way to hook into the upload and pass in the current position of the upload, but not sure. You should look at the docs for that. :)

1 like
phildawson's avatar

@alexanderhempel This kind of thing

$nextPosition = DB::table('uploads')->max('position') + 1; 

// loop
Upload::create([
    ...
    'position' => $nextPosition++, 
]);
// end loop
ohffs's avatar

@alexanderhempel "When i sort by ID, there is no way to update the ID, right?" ... why do you want to? What is the position for?

@thomaskim I'd be a bit wary of relying on that to fix the process - one little slip when adding a dropzone object (or the option changes name sometime) and the app would break again :-) And possibly if multiple people are uploading at the same time it'll trigger the same problem - maybe ;-)

1 like
alexanderhempel's avatar

Thank you EVERBODY! Next time i will take more time on reading docs of the tools i use...

thepsion5's avatar

Are you creating multiple instances of SplashImage but not saving them until after you set the position attribute? That would result in the value of SplashImage::count() being off. Can you post the relevant methods from your model and controller?

alexanderhempel's avatar

@thepsion5
I return the instance to another method and save it there.
The "problem" was that the application is able to process 2 post requests at the same time.
I could fix that, by set the dropzone option "parallelUploads" to 1.

Special thanks to for the hint goes to @thomaskim

1 like

Please or to participate in this conversation.