Optimize MySQL Merge ODKU syntax with field=VALUES(field)

markus_petrux - August 29, 2008 - 11:57
Project:Drupal
Version:7.x-dev
Component:database system
Category:task
Priority:normal
Assigned:Unassigned
Status:closed
Description

Please, excuse me if I missed this in the new DB Layer code. I have just browsed the code from CVS, but it looks to me that a particular feature of MySQL ODKU clausule is not used. ie. field = VALUES(field)

INSERT INTO table (pkey, field_a, field_b) VALUES (1, 2, 3)
  ON DUPLICATE KEY UPDATE
    field_a = VALUES(field_a),
    field_b = VALUES(field_b);

With this syntax it is not necessary to duplicate INSERT values for the ODKU clausule. This may be specially important when big TEXT/BLOB field literals/expressions are invoved, such as db_merge() usage in cache_set().

It has impact on the size of the SQL statemente itself, max_allowed_packet, ...

#1

Crell - August 31, 2008 - 21:51

Hm, interesting. I wasn't aware of that syntax. So you're saying that cache_set, for instance, would become:

INSERT INTO cache (cid, data, expire, created, headers) VALUES ('foo', 'huge string', 0, 12345, NULL) ON DUPLICATE KEY UPDATE cid=values(cid), data=values(data), expire=values(expire), headers=values(headers);

That does seem like a nice optimization. We can probably use that for the default case (just fields()) and for updateExcept(), but not for update(). Can you roll a patch so we can see if it works?

#2

markus_petrux - September 1, 2008 - 00:07
Status:active» needs review

Not exactly. Note that it is not needed to update the key. ie. this is not needed: cid=values(cid)

So the statement would look something like this:

INSERT INTO cache (cid, data, expire, created, headers) VALUES ('foo', 'huge string', 0, 12345, NULL) ON DUPLICATE KEY UPDATE data=values(data), expire=values(expire), headers=values(headers);

Rolling a patch created by looking at the code. It is not tested, but I think it may work, or at least you can get the idea. :)

AttachmentSize
query_odku_values.patch 1.1 KB

#3

markus_petrux - September 1, 2008 - 01:14

Rerolled. $update_fields is not really needed in execute() method.

AttachmentSize
query_odku_values.patch 1.73 KB

#4

markus_petrux - September 1, 2008 - 03:10

I'm very sorry I was not enterily familiar with all merge related methods and I figured I missed the fact that the caller can explicitly specify which fields need to be updated.

Patch re-rolled.

AttachmentSize
query_odku_values.patch 2.42 KB

#5

Crell - September 21, 2008 - 00:10
Status:needs review» needs work

#4 totally doesn't apply at all. :-( I suspect it's because of the whitespace changes that were fixed a week ago. Can you reroll please?

On visual inspection it looks reasonable (and small, which I like), although the comments need a spellcheck and some language cleanup.

#6

markus_petrux - September 21, 2008 - 08:41
Status:needs work» needs review

There you go. This time I believe I have used correct english and technical words. :-/

I wasn't sure whether to include a link to the MySQL manual for this particular syntax. Here's the function VALUES(col_name), if that helps:

http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#func...

AttachmentSize
query_odku.patch 1.6 KB

#7

Dries - September 21, 2008 - 15:33

Looks like a nice optimization, but I'd like to see Crell approve it first.

#8

Crell - September 24, 2008 - 04:31
Status:needs review» reviewed & tested by the community

Looks good to me, and all database tests pass. Sadly there are Windows linebreaks in #6. :-( Attached patch is identical but removes them. Please don't credit me.

This should really help with things like cache sets.

AttachmentSize
query_odku.patch 1.84 KB

#9

Dries - September 27, 2008 - 20:10
Status:reviewed & tested by the community» fixed

Committed to CVS HEAD. Thanks! Welcome back, markus_petrux. :)

#10

Anonymous (not verified) - October 11, 2008 - 20:11
Status:fixed» closed

Automatically closed -- issue fixed for two weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.