0

Please bear with me because I'm hopeless on vocabulary, and my own searches aren't going anywhere.

I've learned here that if I update in the way I want to here (with the GROUP_CONCATs also stored in user-defined vars), I'll lock the entire table.

I'm fairly certain the best way to do this would be to UPDATE row by row in a CURSOR, starting with the highest PK id then descending because I'm sure I will have a lower chance of a deadlock, or conflict, or whatever it's called (told you I was bad with the vocab) if I start from the most recent record.

The column being UPDATEd has no index.

I just found out here that a TRIGGER is a TRANSACTION by default, so I will make a proc instead and call from php.

The transaction isolation level is REPEATABLE-READ.

I'm more concerned with these overlapping UPDATEs causing deadlocks with nothing happening than them taking time to complete.

All tables InnoDB.

All SELECTs and UPDATEs are WHEREd on PK id except for the CURSOR SELECT which SELECTs all ids in the table that's being UPDATEd. No joins. No muss. No fuss.

That said, here finally are the questions:

  1. Will the DECLARE's SELECT only SELECT once, or does that also loop (I'd prefer it to SELECT only once)?
  2. Will the DECLARE's SELECT's lock remain for the duration of the proc (I'd prefer it to release asap)?
  3. Will the row lock for each UPDATE release as soon as the query is finished, or will they remain for the duration of the proc (I'd prefer the row lock release after the individual UPDATE query has finshed)?
  4. Will the SELECTs for the user variables also release after they've been set (you guessed it: I prefer those also to release asap)?
  5. Will it be possible to still SELECT the row being UPDATEd with the row lock (again, I'd prefer if I could)?

Many thanks in advance!

Why UPDATE all on INSERT

In my website (in my profile), I allow users to access all submitted links ever. That's fine on a sequential basis, I simply reference the id.

However, I also rank them on a combined percentile of a custom algorithm on the the 3 vote types, equally weighting the 3.

The problem is that in my algorithm, each vote affects all other votes. There's no way around this because of the nature of my algorithm.

On Demand

I tried that route with PHP. No go. There's too much calculating. I'm not so concerned with users having accurate data instantly because the page will automatically update the ranks for the user with the user being non the wiser, but I can't have the user waiting forever because I allow rapid dynamic pagination.

Calculating in a view was an even greater disaster.

Community
  • 1
  • 1

1 Answers1

1
  • The DECLARE's SELECT will select only once, but I am afraid, that won't help you ...
  • The SELECT cursor might keep something locked from OPEN up to CLOSE - what it is depends on your storage engine: It can be table, page, row or nothing
  • The UPDATE will lock for as long as the update takes. Again, depending on your storage engine, the lock can be table, page or row (but obviously not nothing)

But you might consider a completely different approach: IIUC, you basically want some ranking or percentile match and you try to do this by reacting to every INSERT. This has a big problem in my POV: You calculate lots and lots of unneeded values. What would happen, if you calculate only on a reading operation?

  • If there is allways exactly one INSERT between two reading operations, you have to recalculate allways - same case as if you calculate allways as now.
  • If there are no INSERTs between two reading operations, the MySQL query cache will have kept the result of the prior calculation and will not rerun the query, so you calculate less.
  • If there are more than one INSERTs between two reading operations, you need to calculate only once for N inserts.

So, calculating the rank/percentile on demand will never be more expensive than calculating on INSERT, but it has the potential to be significantly cheaper.

Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92