MySQL’s stored procedure language could be so much more Useful

MySQL has a stored procedure language. People have told me how bad it is, how inefficient, how it had to be there to make MySQL appear more professional. Yes, it’s far from perfect, it’s not pre-compiled so not necessarily any faster than running single statements by hand. However, it works and you can do many useful things with it. The complaints however miss the point of stored procedure languages as used inside a database. They are generally used for 3 things:

  1. To hide the implementation from the database user, so that the implementation can change but the interface remains stable.
  2. To simplify the DBAs day to day tasks of maintaining the database.
  3. To speed up complex queries.

While MySQL doesn’t excel at point 3, it can be used in the other two cases. I’ve used Sybase for quite a while and many maintenance tasks could be fully programmed inside the database, just as you would write a script to do a sequence of events. So you might need to do something like (very made up incorrect example):

@count = 1 -- to get into loop
WHILE @count > 0
BEGIN
    SELECT @var = id FROM some_table WHERE column_name IS NULL LIMIT 1
    SELECT @count = @@rowcount
    IF @count > 0 THEN
        UPDATE other_table set other_column = 'not defined' WHERE some_table_id = @var
    END
END

The above psuedo-code could probably be written in a single statement. Make the logic more complex (add a delay between each iteration, update another table conditionally based on some values) and you might have trouble. The point is you can do this in Sybase. You can do this in Oracle, but you can’t in MySQL, not as an anonymous block of code to be executed immediately from the command line. You would have to write this as a stored procedure, run that stored procedure once and finally drop it afterwards.  Why don’t they allow us to do this directly from the command line?

mysql database_name <<EOF
DELIMITER $$
BEGIN
    statement1;
    statement2;
    -- ...
END
$$
DELIMITER ;
EOF

MySQL 5.0 can’t do this and as far as I know neither 5.1 nor 6.0. Yet creating a stored procedure involves using EXACTLY the same syntax.  Parsing wouldn’t be an issue as the parser is there for the stored functions or procedures. It’s just they need to simply allowing multi-statement input directly from the command line. This would avoid the need for shell or perl scripts just to do mundane tasks and keeps the job within MySQL. Ad-hoc scripting like this would be very useful. Creating a stored procedure to execute a statement block once is just pointless and probably the reason why most people don’t use the stored procedure language that much at the moment.

There are other issues with MySQL’s implementation of stored procedures. In a replication environment you can’t replicate both the CREATE and DROP stored procedure or function calls to the slaves which means that you can’t execute a stored procedure on the master and expect it to run on the slave unless you have set up the slave with the same routines. That’s tedious with one or two slaves but unworkable if the number of slaves increases unless you have special custom tools. It does like look MySQL is addressing this problem which is good news for those of us who could make use of replication to distribute stored procedures to the slaves.

In any case the best way to get people to use the stored procedure language more frequently is to make it accessible directly from the mysql command line.  I’d certainly love to be able to use the language this way. Would you?

Tags: ,

4 Responses to “MySQL’s stored procedure language could be so much more Useful”

  1. sjmudd says:

    I only wrote this yesterday, and today we had a problem. One of our very busy database servers normally has a cleanup script which run every minute and removes old data. That’s been working fine for a long long time. Somehow the script had been turned off. When we realised we turned it back on again. This started causing some problems.

    Why? The cleanup script wasn’t expected to take long. It was designed to delete old data. However there was a lot more data to delete so it took longer. As it took longer it also affected the other active connections which were accessing the same table, and caused some disruption.

    The simple script:

    DELETE FROM table_name WHERE <old_condition> LIMIT <limit>

    was designed to delete small blocks. MySQL however was scanning too much of the index thus causing contention.

    So now we have to adjust the script to:
    - have a few delays between runs
    - to find a better “condition clause” designed to make the index scan faster, and the LIMIT clause if not unnecessary at least less likely to be triggered.

    This is a typical example of what to do in a stored procedure, or perhaps what to do from the command line as a block of mysql code.

    As it is our solution is likely to do the same thing but to run as a script from cron using perl (DBI). Nothing wrong with perl but this is just not needed. It should be doable from the command line.

  2. sjmudd says:

    It seems there is a worklog item to do something about this. See: http://forge.mysql.com/worklog/task.php?id=3696. I am still surprised how few people react to topics like this. I can only guess that having not seen the advantages that they bring they are not aware of what they are missing.

  3. sjmudd says:

    Also there’s a feature request here: http://bugs.mysql.com/48777

  4. andres says:

    i have the same need, creating anonymous code blocks… having to create a procedure to run it once sucks…

Leave a Reply