I am trying to avoid a future problem.
Table has 2 fields:
id -> bigint Primary key
hash -> varchar(65) unique key
there will be concurrent inserts into the table for hash. I need the last insert id
So question:
INSERT INTO table (hash) VALUES(blah) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)
Generate deadlocks if there are 30-50 threads, there is a high chance that these threads will try to insert the same blah?
OR do I need to do:
SELECT id FROM table WHERE hash=blah
if exists GREAT
if doesnt exist:
INSERT IGNORE INTO table (hash) VALUES(blah);
SELECT id FROM table WHERE hash=blah
Edit: Here is the table:
CREATE TABLE `hash_list` (
`id` bigint NOT NULL AUTO_INCREMENT,
`hash` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `hash_UNIQUE` (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
I have no control over the hash. All I need is to store the hash ONCE and get the id many times so it can be used elsewhere in the application. Without deadlocks. This way I get storage savings that will become significant over time.
Edit 2: I've marked danblack's answer as accepted because of the ROW_COUNT() suggestion. But Rick James has valid points as well. Both answers are great!
Edit 3: interestingly with 100+ plus I am seeing 0 deadlocks.
id
looks by theupdate
part of yourinsert
to be the secondary field and hash is the pk? Isvarchar(65)
the smallest the hash can be? considerbinary(X)
and remove any hex, base64 etc encoding on it as you insert it. Withhash
as the pk do you needid
? Do you really want to update theid
on duplicate? or ignore?