NYCPHP Meetup

NYPHP.org

[nycphp-talk] MySQL Tips/Tricks from Sept Newsletter

jon baer jonbaer at jonbaer.net
Tue Sep 30 17:44:21 EDT 2003


http://www.mysql.com/newsletter/2003-09/

MYSQL TIPS & HINTS

Using ORDER BY with UPDATE to resolve the
duplicate key problem

    Indrek Siitan

    To illustrate the problem, let us create a small
    sample table:
    
      CREATE TABLE items (
        id INT NOT NULL PRIMARY KEY,
        name VARCHAR(32)
      ); 
    
    Let's add a couple of rows as well:
    
      INSERT INTO items VALUES (1,'bar'),(2,'qux');
    
    Now, we want to add an entry named "foo" with an
    ID of 1, and shift all of the existing items up by
    one. Easy, you say - just add 1 to the id field
    values and then insert the new row:
    
      UPDATE items SET id=id+1;
      INSERT INTO items VALUES (1,'foo');
    
    In theory, everything looks fine. In real life,
    however, the UPDATE query most probably bails out
    with the following error:
    
      ERROR 1062: Duplicate entry '2' for key 1
    
    This happens because key constraints are checked
    before updating each row (with MyISAM tables that
    are non-transactional, there's no other way, and
    for some reason InnoDB follows the same path). The
    update is done in the order the rows are stored in
    the table files, which, in case you haven't mixed
    DELETEs and INSERTs and caused the table to get
    fragmented, is the order you have inserted the
    rows into the table. So if MySQL starts to process
    the first row and tries to increment the id field
    by 1, the result of 2 already exists in the table
    and produces the error above, although it would be
    increased next and the final query result would
    not violate the key uniqueness.
    
    But not to worry, MySQL has extended the UDPATE
    syntax with a possible ORDER BY clause, that will
    help us solve this problem. If we change the
    update query to:
    
    UPDATE items SET id=id+1 ORDER BY id DESC;
    
    With this ORDER BY clause, MySQL processes rows in
    descending order of id number: First, it updates 2
    to 3, and then 1 to 2.  Consequently, no
    duplicate-key violation occurs and the statement
    succeeds.
    
    The ORDER BY clause in UPDATE is available in
    MySQL server version 4.0.0 and newer.

Is row locking really necessary in multi-table
updates?

    Is row locking really necessary in a multi-table
    update, where some of the tables are only read
    during the update. Couldn't you speed up the
    updates, if the row locking would not be used?
    
    Consider the example below:
    ....
    mysql> create table table1(a int, b int) type =
    innodb;
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> create table table2(a int, b int) type =
    innodb;
    Query OK, 0 rows affected (0.50 sec)
    
    mysql> insert into table1 values (10, 20);
    Query OK, 1 row affected (2.68 sec)
    
    mysql> insert into table2 values (10, 20);
    Query OK, 1 row affected (2.76 sec)
    
    mysql> update table1, table2 set table1.b = 100
    where table1.a = 
    table2.a;
    Query OK, 1 row affected (48.31 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    ....
    
    If we do not lock rows in table2, then the changes
    to table1 are based on an old consistent snapshot
    of table2. If that snapshot is very old, we may
    get really unexpected update results. So it is not
    good idea to set a trap to users by removing the
    row locks on table2.
    
    When you are doing multi-table updates, you might
    run into deadlocks.
    Deadlocks are a problem that needs to be taken
    into account, when using row locking and
    transactions. The link
    http://www.innodb.com/ibman.html#Cope_with_deadlocks
    contains some help in avoiding them.

TIP: Maximum size of a BLOB

    MySQL supports BLOBs (Binary Large Objects), which
    means you can store any binary file into MySQL.
    Many people ask, what is the maximum size of a
    BLOB in MySQL.
    
    The theoretical limit in MySQL 4.0 is 2G, however
    each blob requires generally to have 3 copies of
    it in the memory (stored in various buffers) so
    you need a lot of memory, if you have large BLOBs
    stored in MySQL. This is the reason, why the
    theoretical limit can be reached only on 64bit
    systems. The Practical limits are around some
    hundreds of megs per BLOB.

pgp key: http://www.jonbaer.net/jonbaer.asc
fingerprint: F438 A47E C45E 8B27 F68C 1F9B 41DB DB8B 9A0C AF47




More information about the talk mailing list